diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index f3d4a5f770..e6fa6d7203 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -17,57 +17,56 @@ jobs: strategy: matrix: cfg: - - { name: 'Linux', os: 'ubuntu-22.04' } - - { name: 'MacOS', os: 'macos-13' } + - { name: 'Linux', os: 'ubuntu-24.04' } + - { name: 'MacOS', os: 'macos-15' } steps: - name: checkout uses: actions/checkout@v4 - name: install GNU tools - if: matrix.cfg.os == 'macos-13' + if: matrix.cfg.os == 'macos-15' run: | brew install gnu-sed - echo "/usr/local/opt/gnu-sed/libexec/gnubin" >> ${GITHUB_PATH} + echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> ${GITHUB_PATH} - name: check-source.sh run: ../tools/check-source.sh - name: update brew - if: matrix.cfg.os == 'macos-13' - run: | - brew update + if: matrix.cfg.os == 'macos-15' + run: brew update - name: update-apt-cache - if: matrix.cfg.os == 'ubuntu-22.04' + if: matrix.cfg.os == 'ubuntu-24.04' run: sudo apt-get update - name: install (Linux) - if: matrix.cfg.os == 'ubuntu-22.04' + if: matrix.cfg.os == 'ubuntu-24.04' run: sudo apt-get install latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended lmodern - name: install (MacOS) - if: matrix.cfg.os == 'macos-13' + if: matrix.cfg.os == 'macos-15' run: | brew install basictex eval "$(/usr/libexec/path_helper)" echo "PATH=${PATH}" >> ${GITHUB_ENV} sudo tlmgr update --self - sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs extract layouts enumitem l3packages l3kernel imakeidx splitindex xstring + sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs environ layouts enumitem l3packages l3kernel imakeidx splitindex xstring - name: make (Linux) - if: matrix.cfg.os == 'ubuntu-22.04' + if: matrix.cfg.os == 'ubuntu-24.04' run: make quiet - name: make (MacOS) - if: matrix.cfg.os == 'macos-13' + if: matrix.cfg.os == 'macos-15' run: make full - name: check-output.sh run: ../tools/check-output.sh - name: upload PDF - if: matrix.cfg.os == 'ubuntu-22.04' + if: matrix.cfg.os == 'ubuntu-24.04' uses: actions/upload-artifact@v4 with: name: draft-snapshot diff --git a/.gitorder b/.gitorder index abebabaa77..edc39fbf98 100644 --- a/.gitorder +++ b/.gitorder @@ -5,6 +5,7 @@ source/macros.tex source/tables.tex source/cover-*.tex source/front.tex +source/preface.tex source/intro.tex source/lex.tex source/basic.tex @@ -21,22 +22,24 @@ source/lib-intro.tex source/support.tex source/concepts.tex source/diagnostics.tex +source/memory.tex +source/meta.tex source/utilities.tex -source/strings.tex source/containers.tex source/iterators.tex source/ranges.tex source/algorithms.tex +source/strings.tex +source/text.tex source/numerics.tex source/time.tex -source/locales.tex source/iostreams.tex -source/regex.tex -source/atomics.tex source/threads.tex +source/exec.tex source/grammar.tex source/limits.tex source/compatibility.tex source/future.tex +source/uax31.tex source/back.tex source/xrefdelta.tex diff --git a/papers/n4987.html b/papers/n4987.html new file mode 100644 index 0000000000..3099e7e867 --- /dev/null +++ b/papers/n4987.html @@ -0,0 +1,915 @@ + + + + + +N4987 + + +

N4987 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-07-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

+ + + +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All passed motions from CWG and LWG motions 1 through 9 were applied cleanly. +LWG motions 10, 11, and 12 have not yet been applied due to a lack of time, +but will be included in the next draft.

+ +

In CWG Poll 1, issue CWG2144 contains no wording changes since it is subsumed by CWG2876, which is part of Poll 2. +The wording changes from issue CWG2867 of CWG Poll 1 affect the same wording as CWG Poll 7; the wording has been reconciled.

+ +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except 2819, 2858, and 2876 in +P3345R0 +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the proposed resolution of issues 2819, 2858, and 2876 in +P3345R0 +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper.

+ +

CWG Poll 3. Apply the changes in +P2747R2 +(constexpr placement new) to the C++ Working Paper.

+ +

CWG Poll 5. Apply the changes in +P3144R2 +(Deleting a Pointer to an Incomplete Type Should be Ill-formed) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in +P2963R3 +(Ordering of constraints involving fold expressions) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in +P0963R3 +(Structured binding declaration as a condition) to the C++ Working Paper.

+ +

CWG Poll 4 did not have consensus.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +P3341R0 +(C++ Standard Library Ready Issues to be moved in St. Louis, Jun. 2024) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P2997R1 +(Removing the common reference requirement from the indirectly invocable concepts) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P2389R2 +(dextents Index Type Parameter) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in +P3168R2 +(Give std::optional Range Support) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in +P3217R0 +(Adjoints to "Enabling list-initialization for algorithms": find_last) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in +P2985R0 +(A type trait for detecting virtual base classes) to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in +P0843R14 +(inplace_vector) to the C++ working paper.

+ +

LWG Poll 8. Accept as a Defect Report and apply the changes in +P3235R3 +(std::print more types faster with less memory) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in +P2968R2 +(Make std::ignore a first-class object) to the C++ working paper.

+ +

Not yet applied:

+ +

LWG Poll 10. Apply the changes in +P2075R6 +(Philox as an extension of the C++ RNG engines) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in +P2422R1 +(Remove nodiscard annotations from the standard library specification) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in +P2300R10 +(std::execution) to the C++ working paper.

+ +

Editorial changes

+ +

Major editorial changes

+ +

A number of editorial changes have been applied that resulted from the ongoing review of the +C++23 IS with the ISO secretariat.

+ +

Mathematical formulae are now numbered, and they must be referenced explicitly from the text.

+ +

We avoid writing references as "subclause 1.2.3" in favour of just "1.2.3" now whenever that is +equally clear.

+ +

Examples in Annex C now use the regular example style, as opposed to the previous ad-hoc style.

+ +

We changed how we refer to the C++ standard itself and how we cite other standards. The page +footers have been changed to show the page number and the copyright over two lines, and the +display of Annex titles has been changed, both in accordance with new ISO style advice. For +details see the following listing.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4981 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 59d6bfc0c23b61cabb72d9a48270ed1c3b7e02f9
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Apr 16 09:57:19 2024 -0400
+
+    [basic.life] Reflow text defining transparently replaceable
+
+    p8 is difficult to read as it defines transparently replaceable
+    only after it has made all use of it.  The edit pulls the
+    definition of transparently replaceable into its own preceding
+    paragraph, and then simplifies the sentence that uses this term.
+
+commit ccfb6adea4373a63b7063f4d41cb9d47876a9347
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Apr 17 03:08:36 2024 -0400
+
+    [tab:headers.cpp.fs] Move the debugging library to numberically sorted position (#6927)
+
+commit c82e95ca91b313bc2cfde60aac9abbd49406d930
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Apr 17 18:42:19 2024 -0400
+
+    [zombie.names] Turn lists of zombie names into tables (#6925)
+
+commit c1eec01966d6383dabfaa4304939ce3be3868f1f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Apr 18 23:51:53 2024 +0800
+
+    [range.concat.overview] Remove unnecessary `std::` prefix from example (#6931)
+
+commit 2de15529d3f98a5de25cecf9ac8ed5b104d776e1
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Apr 18 18:00:42 2024 +0200
+
+    [charconv.syn] Clarify types matching integer-type (#6847)
+
+commit bae18b69cbca566eac284c8c2f316407fda98d16
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Apr 19 01:21:19 2024 +0800
+
+    [range.concat.view] Format code to match the current style (#6929)
+
+commit 79dcca82c22d75fc2b2b6cbc1c338a0229db9a34
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Apr 19 19:51:29 2024 +0800
+
+    [range.utility.conv.general] Fix misapplication of LWG4016 (#6932)
+
+commit e572580d71dfc8bdb32b8d1a21a2e493676e2151
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Apr 19 21:57:48 2024 +0800
+
+    [range.concat.iterator] Remove @ outside of codeblocks (#6934)
+
+commit 5a5295d9c9e1881e58d3b4696fe45f00ef1cc507
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Apr 19 17:32:53 2024 -0400
+
+    [index] Add missing entries for Cpp17 concepts (#6940)
+
+commit 5d4d9508bca4709366a0ff7acb17ba7b3a2efced
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Apr 20 20:16:23 2024 +0800
+
+    [range.join.with.iterator] Add missing 'template' keyword for dependent name 'emplace' (#5455)
+
+commit 0ac38fd4c4548ff61cd378f98eff3e18f4463caf
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Aug 18 15:12:08 2023 +0800
+
+    Fix typo (`dynamic_rank` => `rank_dynamic`)
+
+commit 47c2f68d84cb13a7ca83a507fb1f32ddf4774ec1
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Apr 22 23:19:41 2024 +0200
+
+    [mdspan.layout.leftpad.obs] Remove superfluous \item (#6944)
+
+commit 4f0779d5a3665af9dd92a96e52d809ba3911495d
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Apr 23 12:13:27 2024 +0200
+
+    [intro.execution] Add comma after conditional clause (#6945)
+
+commit 12b6307589257a803527eb38c43f08f867d59322
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Apr 29 15:23:41 2024 +0800
+
+    [algorithm.syn,alg.fill] Fix typos in constraints (#6957)
+
+commit 927d0dba2b068ba9f2136479b4ba05a430eec348
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Apr 29 22:43:49 2024 +0800
+
+    [alg.rand.generate] Remove brace typo (#6956)
+
+commit 480adbe4d6ae54e03b6cec5f8784689445c36eee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 30 07:48:14 2024 +0200
+
+    [print.syn] Correctly order println overloads
+
+commit 3333421819c1b2c6dec1becd0dd2a9fa0aeba8cd
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Apr 30 20:22:43 2024 +0800
+
+    [range.concat.iterator] Remove superfluous period (#6960)
+
+commit 513635b371c6a664be2a0ea6fc6939350b9b5e6b
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri May 10 00:17:43 2024 +0800
+
+    [range.reverse.overview] Replace 'equivalent to' with 'then' (#6966)
+
+commit be18ecc17114bcae4acdad10a3467686510b22c2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat May 11 21:51:48 2024 +0200
+
+    [class.derived.general] Restore accidental reversal of P2662R3 change
+
+    P2662R3 contained a rename of the grammar production "class-or-decltype"
+    to "class-or-computed-type-specifier".  That was editorially reverted
+    with commit c831ec0b8aac369aa61ce392783865ff04b84b19, but that commit
+    also accidentally reverted the change from "decltype-specifier" to
+    "computed-type-specifier" as one of the options for "class-or-decltype".
+
+    This commit restores the latter change, as intended by P2662R3.
+
+commit 9dcff41d2d26577c2ec0643056187a0f8094832e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun May 12 15:24:43 2024 +0100
+
+    [intro.refs] Fix document titles
+
+commit 5b332fed1a4577ad08ed469da26c9c7864ea9e11
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun May 12 15:31:43 2024 +0100
+
+    [intro.refs, intro.defs] Update ISO 80000-2:2009 to :2019, change "and" to comma
+
+commit 85f4bb454effe50029de636d6f206f9c1153236a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun May 12 15:53:11 2024 +0100
+
+    [defns.order.ptr] Add missing hypen in "built-in"
+
+commit 9cd8d6ce9cc446c94d91e1350b9113906774f0af
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue May 14 21:49:55 2024 +0800
+
+    [format.context] Fix error in example (#6970)
+
+commit 951ded4880e4295981c0d691915a81d84c2baa9d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun May 12 16:01:09 2024 +0100
+
+    [defns.unblock] Italicize entire term "blocked", not just "block".
+
+    ISO has indicated that this is the acceptable way to state a reference to another definition, in this case "block" [defns.block].
+
+commit 1cb3842f83412720a23c664f478a4167cb3162a2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 18:52:30 2024 +0200
+
+    [styles] Redesign Annex titles per Rice Model Standard
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 2f23560744a966f7a455629506468a02055d53ea
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon May 20 05:52:26 2024 -0400
+
+    [alg.ends.with] Replace drop_view with views::drop (#6773)
+
+commit bbac8a98d303d3ad5ecd9514fb2db37745d16984
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon May 20 07:24:27 2024 -0400
+
+    [dcl.init.list] Eliminate "specialization of initializer_list<X>" (#6258)
+
+commit ad37b863dec4af4c88d8f2154d5f3e4a9b2a3b33
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue May 21 07:12:32 2024 -0400
+
+    [support.initlist] "initializer list" should be "initializer_list" (#6680)
+
+    This note is talking about the class type, not the grammatical construct.
+
+commit 2e455af5d6a2bdaac7e9d0d4e7f23ac7a6c0451d
+Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com>
+Date:   Tue May 21 22:50:56 2024 -0700
+
+    [util.smartptr.shared.cast] Properly describe possibility of double deletion in notes (#7037)
+
+commit 4b3f32ae814c8da3faccc0dc307904bd250371d9
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 28 22:10:36 2024 +0100
+
+    [input.output] Add cross-references to header synopses (#7005)
+
+    Several of the synopses are not adjacent to the types they declare.
+    Adding cross-references makes it easier to find the relevant definitions
+    of classes and class templates.
+
+    Also make the title of [ostream.manip] more specific to its content.
+
+commit dbf17528619707307f859bac1b36c52654fecfc8
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon Jun 10 17:06:15 2024 -0400
+
+    [container.adaptors] Reorder constructors for flat_* adaptors (#6274)
+
+    Canonicalize the ordering of the constructors for the flat_* adaptors:
+     - default constructor is first
+     - each overload without `key_compare` is followed by the corresponding one with `key_compare`
+     - each pair of overloads without `sorted_unique` is followed by the corresponding pair with `sorted_unique`
+
+commit ae9b2d7481af415076ffdf33d5920e31e5591eb1
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Jun 11 15:32:36 2024 +0200
+
+    [res.on.exception.handling] Add cross-reference to [except.spec] (#7058)
+
+commit c95ff039b634388962e1fa242e772da8466d49b6
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Jun 12 12:36:02 2024 +0200
+
+    [stmt.if] Add missing comma after conditional clause (#7061)
+
+commit 42a38b072a471a112720535c087d96c8f4865a47
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Jun 12 18:56:14 2024 +0200
+
+    [stmt.pre] Add a cross-reference to [intro.execution] (#7060)
+
+commit 3680e10a5a7eb48b35f150429ce6b3313583bb87
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Jun 14 12:48:46 2024 +0200
+
+    [class.virtual] Add commas (#7062)
+
+commit 9ad7d63f8db28c88dfa68866d23c5ab742be3f80
+Author: Antony Polukhin <antoshkka@gmail.com>
+Date:   Tue Jun 18 19:00:34 2024 +0300
+
+    [associative.reqmts.general] Fix typo (#7069)
+
+commit a24620eced94b1f04fcbd8add49f5e9ca6326ed4
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jun 21 12:36:01 2024 +0200
+
+    [class.union.general] Add comma (#7072)
+
+commit 59e634a8a841f58efeac873459bedf28928a83f9
+Author: Johannes Sixt <j6t@kdbg.org>
+Date:   Wed Jun 26 11:53:47 2024 +0200
+
+    [func.require] Add missing formatting of subscript index (#7071)
+
+commit 6d67d200863e430650047adb651324bc5663b6fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 13:13:42 2024 +0200
+
+    [diff] Mark examples as such
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 21e022557462544e2e6d32411f71e42a378d2236
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Jul 2 14:31:08 2024 +0100
+
+    [depr.c.macros] Fix "macro" singular when referring to two macros
+
+    This should have been applied as part of LWG 4036.
+
+commit 8bb63636c37f8e67808de1e1ce1142a3028293fd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jul 3 20:53:40 2024 +0100
+
+    [istream.unformatted] add missing semi-colon to list item (#7117)
+
+commit 8227c196af96f157a539e5181f7a75ab3de3a096
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jul 5 10:03:47 2024 +0200
+
+    [except.throw] Add comma (#7118)
+
+commit 07c20b75a867b66c858de716dfb639b0a9d1da2c
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Sat Jul 6 23:32:43 2024 +0800
+
+    [version.syn] Remove redundant <version> for __cpp_lib_ranges_enumerate (#7120)
+
+commit 15b7ea6c95e471888cda2c334ba8ac30cabccf64
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Jul 7 10:23:09 2024 +0200
+
+    [basic.start.main] fix definite article (#7121)
+
+commit 61d85d3f9b78d792bd1bdb1d15202f9cdd931b31
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 00:57:58 2024 +0100
+
+    [intro.compliance.general] Cite Annex B more normatively.
+
+commit 2048179f82bbe92dcccee3cc6bbdac4973c77606
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 01:25:28 2024 +0100
+
+    [intro.compliance.general] Cite Annex D more normatively.
+
+commit 6b67a856495634df3a0bd0d8abee36eb0d3c8c6f
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jul 9 08:29:50 2024 +0200
+
+    [temp.inst] Fix definite article
+
+commit 43c47b42fd1f7cd4d095299aca98666c06e45949
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 01:44:08 2024 +0100
+
+    [uaxid] Clarify that requirements come "from UAX #31", and use "this document".
+
+commit 7c35cb057ef4885e091bf65c1103d64946e7c8d1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 14:47:10 2024 +0100
+
+    [std] Make bibliography reference link colour more citely
+
+commit bc2c80c23133a0581a847bd7fcfaca621ca86ffe
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 20:17:21 2024 +0200
+
+    [dcl.init.list] Add commas and period for bulleted list
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 868db7356ad1490890391e8c82888de5c4d4aad4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 20:18:20 2024 +0200
+
+    [facet.num.get.virtuals] Add missing punctuation
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 77ee6ed3b8865b2bb514cb8446488aa6fb032dda
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 23:39:13 2024 +0200
+
+    [lex.literal] Properly format table headings
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit cb9850377b88a4d7da12d05bcdf11948c384f699
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 23:47:55 2024 +0200
+
+    [basic.fundamental] Center second column of "integer width" table
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 2a2b8732e0d81dd9f5d3880b70bd451173e5f5fc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 15:41:56 2024 +0100
+
+    [intro.defs] Minor rewording. Avoid sounding like a requirement.
+
+commit 4746925c7117015480542fd68ad5f595b78173d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 14:11:53 2024 +0200
+
+    [numeric.limits.members,bibliography] Remove LIA-1 abbreviation for ISO 10967
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit c18d51ddf436abf39065ea86497161383bba11c0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 09:05:36 2024 +0200
+
+    [intro.memory] Move footnote about Unicode trademark to [lex.phases]
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 1f32f6aa8000f194f1b5c4daba94d271eea817fb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 16:28:34 2024 +0200
+
+    [diff,bibliography] Move details of old C++ standards to the bibliography
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit d5410b4035e3108d48a63434abfff7e377c996d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 18:31:14 2024 +0200
+
+    [diff.cpp20,diff.cpp17] Add missing inclusion clause
+
+commit af4cf904c3d2df0675dbd456af2de2f1259e370c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 12:56:12 2024 +0200
+
+    [std] Rename 'In general' headings to 'General' for consistency
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 9d3011b4224bb63636f4a117967e8ba8110f5ba4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 17 14:11:48 2024 +0200
+
+    [implimits] Rephrase introductory sentence for list of quantities
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 260d3a0d0cde1431dd4221115e1b37979ee07e7d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 12:30:44 2024 +0200
+
+    [class.copy.ctor] Remove reference to non-existing example
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 0bc3e030be28ff2191af8e9c9c202bff6e23c320
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 12:37:12 2024 +0200
+
+    [class.conv.general] Remove vague reference to unhelpful examples
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 861f07de24c5cfbd69840038d8589bc13b24b7e7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 21:58:36 2024 +0200
+
+    [cpp.predefined,namespace.future,version.syn] Replace 'C++' with 'this document'
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit a7a2cbd10ea752d49ca286e3fea3e7cbbb9b6e9d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 17 00:44:32 2024 +0200
+
+    [futures.state] Turn note into example
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 88c48bb78815576fb20db42b89f381c580d28b0e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 22:41:24 2024 +0200
+
+    [std] Remove colons in front of bulleted lists
+
+commit 9d7aa6108b84a09117463d0b13bc24cf61926897
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 22:47:38 2024 +0200
+
+    [iterators] Add colon after 'model ... only if' when complete sentences follow
+
+commit 79ac47f7053da4ef20c117e282377591d028e7a5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 21:42:09 2024 +0200
+
+    [basic.fundamental,cstdarg.syn] Use full reference for ISO C sections
+
+    Fixes ISO/CS comment (C++23)
+
+commit 2bbf136502811925250b09fd73909b78e0236091
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 12:51:32 2024 +0200
+
+    [execpol.general] Use 'this document', not 'this standard'
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit e65393f3c87d323258e38c498b849dc57404a20b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 22:13:14 2024 +0200
+
+    [format.string.std] Add (R) symbol after Windows
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit dafefea895de358b8edcb6780e3c7b71d209b458
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 19:12:57 2024 +0200
+
+    [rand.req] Replace 'that Table' with a precise reference
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 361e7769a245aad263574bbe83b9266d8da3b01b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 17 09:42:22 2024 +0200
+
+    [std] Replace 'this standard' with 'this document'
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit e86031dd14e052956fc23ec4dbc1510b7438ba5b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 23:19:57 2024 +0200
+
+    [time.format,time.parse] Fix references to ISO week calendar
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 868b0b29ac16370ed8792442a0ab41be91c5d575
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 19:01:05 2024 +0200
+
+    [std] Avoid hanging paragraphs by introducing "General" subclauses
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit f0580700cf0e8e920ceb3a078b6872a4c16fa225
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 15 21:49:31 2024 +0200
+
+    [std] Remove ISO from any mention of 'C'
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 69f184ea599635dac4cd9dc06a3303bed93b26f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 19:30:38 2024 +0200
+
+    [std] Remove mid-sentence 'subclause' introducer
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit ecb071672b02a4b7bc829f87433d98785d9dd701
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 13 19:44:40 2024 +0200
+
+    [std] Remove incorrect or duplicative 'this subclause' introducers
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit a249f9f37531fe79e768f19a45f1b1a70685c2c6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 22:48:20 2024 +0100
+
+    [classes] Turn ad-hoc examples into proper examples (#7125)
+
+commit eade3851e174ac014b478b8d4f097103d3b996ae
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 12:44:01 2024 +0200
+
+    [lex.ccon,expr.prim.lambda.capture] Excise 'ISO' prefix
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 5383169856690cf05d946f058ed861119405d126
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 14:32:49 2024 +0200
+
+    [fs.class.path.general] Defuse cross-reference to POSIX
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 5731ab6a9122763bf6193d1382a05c7bebe82b38
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 9 23:24:09 2024 +0100
+
+    [time.format] Remove mid-sentence 'subclause' introducer from external reference
+
+commit 856d175973d343d8e16d641221f47357672d9959
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 17 14:26:54 2024 +0200
+
+    [lib] Excise Note A, Note B, etc. designations
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 5508a007540d790a8f5cd30f863f4d329edf2694
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 16 15:07:27 2024 +0200
+
+    [macros,numerics] Add and use numbered 'formula' environment
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 2b0ff8d6bd285bbe8b27fdab47e268b115a3f930
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 10 11:33:23 2024 +0100
+
+    [lex.string] Replace colon with full stop to end the sentence.
+
+    On request of ISO/CS, for otherwise we should have made the next 'if'
+    lowercase, because: "Grammatically this is the same sentence,
+    as there is no full stop, so the 'if' should be lowercase."
+
+    If a colon really doesn't end a sentence, then we should make it so
+    that the sentence really does end.
+
+commit 064fb0b34eb8cbb14f52dc966c833ef7c749c82c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 14 08:23:07 2024 +0200
+
+    [macros] Prefer page break above 'note' or 'example' introducers
+
+    Fixes ISO/CS comment (C++23 proof)
+
+commit 13b08d0f58dfea7ae2e19b1d931094d4523a52d2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 11 01:41:29 2024 +0100
+
+    [layout, styles] New ISO header and footer layout.
+
+    The footer now takes up two lines, one for the copyright and one for
+    the page number.
+
+commit 7f6069c794abb56e51affdc2923e3d33b3a547a8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 11 12:27:28 2024 +0100
+
+    [cover-reg] Update regular cover
+
+commit f41a619cf852ae638bfe4792ec78ac1f214a7d23
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 12 01:28:38 2024 +0100
+
+    [impldefindex] Reinstate full page mark
+
+    As of 13b08d0f58dfea7ae2e19b1d931094d4523a52d2 we have space for it.
+
+commit b2870b5c87765946f5c4a644da508adcc483045e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 12 01:30:06 2024 +0100
+
+    [macros, std] Create macros for ISO/IEC 60559 and ISO/IEC/IEEE 9945.
+
+    As a side effect, this corrects the title of ISO/IEC 60559(:2020),
+    whose previous version was ISO/IEC/IEEE 60559:2011.
+
+ + diff --git a/papers/n4987.md b/papers/n4987.md new file mode 100644 index 0000000000..d405f0b427 --- /dev/null +++ b/papers/n4987.md @@ -0,0 +1,774 @@ +# N4987 Editors' Report -- Programming Languages -- C++ + +Date: 2024-07-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 + + * [N4986](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf) is the + current working draft for C++26. It replaces + [N4981](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4981.pdf). + * N4987 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +All passed motions from CWG and LWG motions 1 through 9 were applied cleanly. +LWG motions 10, 11, and 12 have not yet been applied due to a lack of time, +but will be included in the next draft. + +In CWG Poll 1, issue CWG2144 contains no wording changes since it is subsumed by CWG2876, which is part of Poll 2. +The wording changes from issue CWG2867 of CWG Poll 1 affect the same wording as CWG Poll 7; the wording has been reconciled. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except 2819, 2858, and 2876 in +[P3345R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3345r0.html) +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the proposed resolution of issues 2819, 2858, and 2876 in +[P3345R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3345r0.html) +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper. + +CWG Poll 3. Apply the changes in +[P2747R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2747r2.html) +(`constexpr` placement new) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in +[P3144R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3144r2.pdf) +(Deleting a Pointer to an Incomplete Type Should be Ill-formed) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in +[P2963R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2963r3.pdf) +(Ordering of constraints involving fold expressions) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in +[P0963R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0963r3.html) +(Structured binding declaration as a condition) to the C++ Working Paper. + +CWG Poll 4 did not have consensus. + +### Library working group polls + +LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +[P3341R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3341r0.html) +(C++ Standard Library Ready Issues to be moved in St. Louis, Jun. 2024) to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P2997R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2997r1.html) +(Removing the common reference requirement from the indirectly invocable concepts) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P2389R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2389r2.html) +(`dextents` Index Type Parameter) to the C++ working paper. + +LWG Poll 4. Apply the changes in +[P3168R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3168r2.html) +(Give `std::optional` Range Support) to the C++ working paper. + +LWG Poll 5. Apply the changes in +[P3217R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3217r0.html) +(Adjoints to "Enabling list-initialization for algorithms": `find_last`) to the C++ working paper. + +LWG Poll 6. Apply the changes in +[P2985R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2985r0.html) +(A type trait for detecting virtual base classes) to the C++ working paper. + +LWG Poll 7. Apply the changes in +[P0843R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0843r14.html) +(`inplace_vector`) to the C++ working paper. + +LWG Poll 8. Accept as a Defect Report and apply the changes in +[P3235R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3235r3.html) +(std::print more types faster with less memory) to the C++ working paper. + +LWG Poll 9. Apply the changes in +[P2968R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2968r2.html) +(Make std::ignore a first-class object) to the C++ working paper. + +**Not yet applied:** + +LWG Poll 10. Apply the changes in +[P2075R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2075r6.html) +(Philox as an extension of the C++ RNG engines) to the C++ working paper. + +LWG Poll 11. Apply the changes in +[P2422R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2422r1.html) +(Remove nodiscard annotations from the standard library specification) to the C++ working paper. + +LWG Poll 12. Apply the changes in +[P2300R10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html) +(std::execution) to the C++ working paper. + +## Editorial changes + +### Major editorial changes + +A number of editorial changes have been applied that resulted from the ongoing review of the +C++23 IS with the ISO secretariat. + +Mathematical formulae are now numbered, and they must be referenced explicitly from the text. + +We avoid writing references as "subclause 1.2.3" in favour of just "1.2.3" now whenever that is +equally clear. + +Examples in Annex C now use the regular example style, as opposed to the previous ad-hoc style. + +We changed how we refer to the C++ standard itself and how we cite other standards. The page +footers have been changed to show the page number and the copyright over two lines, and the +display of Annex titles has been changed, both in accordance with new ISO style advice. For +details see the following listing. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4981 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/n4981...n4986). + + commit 59d6bfc0c23b61cabb72d9a48270ed1c3b7e02f9 + Author: Alisdair Meredith + Date: Tue Apr 16 09:57:19 2024 -0400 + + [basic.life] Reflow text defining transparently replaceable + + p8 is difficult to read as it defines transparently replaceable + only after it has made all use of it. The edit pulls the + definition of transparently replaceable into its own preceding + paragraph, and then simplifies the sentence that uses this term. + + commit ccfb6adea4373a63b7063f4d41cb9d47876a9347 + Author: Alisdair Meredith + Date: Wed Apr 17 03:08:36 2024 -0400 + + [tab:headers.cpp.fs] Move the debugging library to numberically sorted position (#6927) + + commit c82e95ca91b313bc2cfde60aac9abbd49406d930 + Author: Alisdair Meredith + Date: Wed Apr 17 18:42:19 2024 -0400 + + [zombie.names] Turn lists of zombie names into tables (#6925) + + commit c1eec01966d6383dabfaa4304939ce3be3868f1f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Apr 18 23:51:53 2024 +0800 + + [range.concat.overview] Remove unnecessary `std::` prefix from example (#6931) + + commit 2de15529d3f98a5de25cecf9ac8ed5b104d776e1 + Author: Jan Schultke + Date: Thu Apr 18 18:00:42 2024 +0200 + + [charconv.syn] Clarify types matching integer-type (#6847) + + commit bae18b69cbca566eac284c8c2f316407fda98d16 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Apr 19 01:21:19 2024 +0800 + + [range.concat.view] Format code to match the current style (#6929) + + commit 79dcca82c22d75fc2b2b6cbc1c338a0229db9a34 + Author: S. B. Tam + Date: Fri Apr 19 19:51:29 2024 +0800 + + [range.utility.conv.general] Fix misapplication of LWG4016 (#6932) + + commit e572580d71dfc8bdb32b8d1a21a2e493676e2151 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Apr 19 21:57:48 2024 +0800 + + [range.concat.iterator] Remove @ outside of codeblocks (#6934) + + commit 5a5295d9c9e1881e58d3b4696fe45f00ef1cc507 + Author: Alisdair Meredith + Date: Fri Apr 19 17:32:53 2024 -0400 + + [index] Add missing entries for Cpp17 concepts (#6940) + + commit 5d4d9508bca4709366a0ff7acb17ba7b3a2efced + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Apr 20 20:16:23 2024 +0800 + + [range.join.with.iterator] Add missing 'template' keyword for dependent name 'emplace' (#5455) + + commit 0ac38fd4c4548ff61cd378f98eff3e18f4463caf + Author: S. B. Tam + Date: Fri Aug 18 15:12:08 2023 +0800 + + Fix typo (`dynamic_rank` => `rank_dynamic`) + + commit 47c2f68d84cb13a7ca83a507fb1f32ddf4774ec1 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Apr 22 23:19:41 2024 +0200 + + [mdspan.layout.leftpad.obs] Remove superfluous \item (#6944) + + commit 4f0779d5a3665af9dd92a96e52d809ba3911495d + Author: Jan Schultke + Date: Tue Apr 23 12:13:27 2024 +0200 + + [intro.execution] Add comma after conditional clause (#6945) + + commit 12b6307589257a803527eb38c43f08f867d59322 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Apr 29 15:23:41 2024 +0800 + + [algorithm.syn,alg.fill] Fix typos in constraints (#6957) + + commit 927d0dba2b068ba9f2136479b4ba05a430eec348 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Apr 29 22:43:49 2024 +0800 + + [alg.rand.generate] Remove brace typo (#6956) + + commit 480adbe4d6ae54e03b6cec5f8784689445c36eee + Author: Jens Maurer + Date: Tue Apr 30 07:48:14 2024 +0200 + + [print.syn] Correctly order println overloads + + commit 3333421819c1b2c6dec1becd0dd2a9fa0aeba8cd + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Apr 30 20:22:43 2024 +0800 + + [range.concat.iterator] Remove superfluous period (#6960) + + commit 513635b371c6a664be2a0ea6fc6939350b9b5e6b + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri May 10 00:17:43 2024 +0800 + + [range.reverse.overview] Replace 'equivalent to' with 'then' (#6966) + + commit be18ecc17114bcae4acdad10a3467686510b22c2 + Author: Jens Maurer + Date: Sat May 11 21:51:48 2024 +0200 + + [class.derived.general] Restore accidental reversal of P2662R3 change + + P2662R3 contained a rename of the grammar production "class-or-decltype" + to "class-or-computed-type-specifier". That was editorially reverted + with commit c831ec0b8aac369aa61ce392783865ff04b84b19, but that commit + also accidentally reverted the change from "decltype-specifier" to + "computed-type-specifier" as one of the options for "class-or-decltype". + + This commit restores the latter change, as intended by P2662R3. + + commit 9dcff41d2d26577c2ec0643056187a0f8094832e + Author: Thomas Köppe + Date: Sun May 12 15:24:43 2024 +0100 + + [intro.refs] Fix document titles + + commit 5b332fed1a4577ad08ed469da26c9c7864ea9e11 + Author: Thomas Köppe + Date: Sun May 12 15:31:43 2024 +0100 + + [intro.refs, intro.defs] Update ISO 80000-2:2009 to :2019, change "and" to comma + + commit 85f4bb454effe50029de636d6f206f9c1153236a + Author: Thomas Köppe + Date: Sun May 12 15:53:11 2024 +0100 + + [defns.order.ptr] Add missing hypen in "built-in" + + commit 9cd8d6ce9cc446c94d91e1350b9113906774f0af + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue May 14 21:49:55 2024 +0800 + + [format.context] Fix error in example (#6970) + + commit 951ded4880e4295981c0d691915a81d84c2baa9d + Author: Thomas Köppe + Date: Sun May 12 16:01:09 2024 +0100 + + [defns.unblock] Italicize entire term "blocked", not just "block". + + ISO has indicated that this is the acceptable way to state a reference to another definition, in this case "block" [defns.block]. + + commit 1cb3842f83412720a23c664f478a4167cb3162a2 + Author: Jens Maurer + Date: Tue May 14 18:52:30 2024 +0200 + + [styles] Redesign Annex titles per Rice Model Standard + + Fixes ISO/CS comment (C++23 proof) + + commit 2f23560744a966f7a455629506468a02055d53ea + Author: Arthur O'Dwyer + Date: Mon May 20 05:52:26 2024 -0400 + + [alg.ends.with] Replace drop_view with views::drop (#6773) + + commit bbac8a98d303d3ad5ecd9514fb2db37745d16984 + Author: Arthur O'Dwyer + Date: Mon May 20 07:24:27 2024 -0400 + + [dcl.init.list] Eliminate "specialization of initializer_list" (#6258) + + commit ad37b863dec4af4c88d8f2154d5f3e4a9b2a3b33 + Author: Arthur O'Dwyer + Date: Tue May 21 07:12:32 2024 -0400 + + [support.initlist] "initializer list" should be "initializer_list" (#6680) + + This note is talking about the class type, not the grammatical construct. + + commit 2e455af5d6a2bdaac7e9d0d4e7f23ac7a6c0451d + Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com> + Date: Tue May 21 22:50:56 2024 -0700 + + [util.smartptr.shared.cast] Properly describe possibility of double deletion in notes (#7037) + + commit 4b3f32ae814c8da3faccc0dc307904bd250371d9 + Author: Jonathan Wakely + Date: Tue May 28 22:10:36 2024 +0100 + + [input.output] Add cross-references to header synopses (#7005) + + Several of the synopses are not adjacent to the types they declare. + Adding cross-references makes it easier to find the relevant definitions + of classes and class templates. + + Also make the title of [ostream.manip] more specific to its content. + + commit dbf17528619707307f859bac1b36c52654fecfc8 + Author: Arthur O'Dwyer + Date: Mon Jun 10 17:06:15 2024 -0400 + + [container.adaptors] Reorder constructors for flat_* adaptors (#6274) + + Canonicalize the ordering of the constructors for the flat_* adaptors: + - default constructor is first + - each overload without `key_compare` is followed by the corresponding one with `key_compare` + - each pair of overloads without `sorted_unique` is followed by the corresponding pair with `sorted_unique` + + commit ae9b2d7481af415076ffdf33d5920e31e5591eb1 + Author: Jan Schultke + Date: Tue Jun 11 15:32:36 2024 +0200 + + [res.on.exception.handling] Add cross-reference to [except.spec] (#7058) + + commit c95ff039b634388962e1fa242e772da8466d49b6 + Author: Jan Schultke + Date: Wed Jun 12 12:36:02 2024 +0200 + + [stmt.if] Add missing comma after conditional clause (#7061) + + commit 42a38b072a471a112720535c087d96c8f4865a47 + Author: Jan Schultke + Date: Wed Jun 12 18:56:14 2024 +0200 + + [stmt.pre] Add a cross-reference to [intro.execution] (#7060) + + commit 3680e10a5a7eb48b35f150429ce6b3313583bb87 + Author: Jan Schultke + Date: Fri Jun 14 12:48:46 2024 +0200 + + [class.virtual] Add commas (#7062) + + commit 9ad7d63f8db28c88dfa68866d23c5ab742be3f80 + Author: Antony Polukhin + Date: Tue Jun 18 19:00:34 2024 +0300 + + [associative.reqmts.general] Fix typo (#7069) + + commit a24620eced94b1f04fcbd8add49f5e9ca6326ed4 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jun 21 12:36:01 2024 +0200 + + [class.union.general] Add comma (#7072) + + commit 59e634a8a841f58efeac873459bedf28928a83f9 + Author: Johannes Sixt + Date: Wed Jun 26 11:53:47 2024 +0200 + + [func.require] Add missing formatting of subscript index (#7071) + + commit 6d67d200863e430650047adb651324bc5663b6fc + Author: Jens Maurer + Date: Tue May 14 13:13:42 2024 +0200 + + [diff] Mark examples as such + + Fixes ISO/CS comment (C++23 proof) + + commit 21e022557462544e2e6d32411f71e42a378d2236 + Author: Jonathan Wakely + Date: Tue Jul 2 14:31:08 2024 +0100 + + [depr.c.macros] Fix "macro" singular when referring to two macros + + This should have been applied as part of LWG 4036. + + commit 8bb63636c37f8e67808de1e1ce1142a3028293fd + Author: Jonathan Wakely + Date: Wed Jul 3 20:53:40 2024 +0100 + + [istream.unformatted] add missing semi-colon to list item (#7117) + + commit 8227c196af96f157a539e5181f7a75ab3de3a096 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jul 5 10:03:47 2024 +0200 + + [except.throw] Add comma (#7118) + + commit 07c20b75a867b66c858de716dfb639b0a9d1da2c + Author: Yihe Li + Date: Sat Jul 6 23:32:43 2024 +0800 + + [version.syn] Remove redundant for __cpp_lib_ranges_enumerate (#7120) + + commit 15b7ea6c95e471888cda2c334ba8ac30cabccf64 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Jul 7 10:23:09 2024 +0200 + + [basic.start.main] fix definite article (#7121) + + commit 61d85d3f9b78d792bd1bdb1d15202f9cdd931b31 + Author: Thomas Köppe + Date: Tue Jul 9 00:57:58 2024 +0100 + + [intro.compliance.general] Cite Annex B more normatively. + + commit 2048179f82bbe92dcccee3cc6bbdac4973c77606 + Author: Thomas Köppe + Date: Tue Jul 9 01:25:28 2024 +0100 + + [intro.compliance.general] Cite Annex D more normatively. + + commit 6b67a856495634df3a0bd0d8abee36eb0d3c8c6f + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jul 9 08:29:50 2024 +0200 + + [temp.inst] Fix definite article + + commit 43c47b42fd1f7cd4d095299aca98666c06e45949 + Author: Thomas Köppe + Date: Tue Jul 9 01:44:08 2024 +0100 + + [uaxid] Clarify that requirements come "from UAX #31", and use "this document". + + commit 7c35cb057ef4885e091bf65c1103d64946e7c8d1 + Author: Thomas Köppe + Date: Tue Jul 9 14:47:10 2024 +0100 + + [std] Make bibliography reference link colour more citely + + commit bc2c80c23133a0581a847bd7fcfaca621ca86ffe + Author: Jens Maurer + Date: Mon May 13 20:17:21 2024 +0200 + + [dcl.init.list] Add commas and period for bulleted list + + Fixes ISO/CS comment (C++23 proof) + + commit 868db7356ad1490890391e8c82888de5c4d4aad4 + Author: Jens Maurer + Date: Mon May 13 20:18:20 2024 +0200 + + [facet.num.get.virtuals] Add missing punctuation + + Fixes ISO/CS comment (C++23 proof) + + commit 77ee6ed3b8865b2bb514cb8446488aa6fb032dda + Author: Jens Maurer + Date: Mon May 13 23:39:13 2024 +0200 + + [lex.literal] Properly format table headings + + Fixes ISO/CS comment (C++23 proof) + + commit cb9850377b88a4d7da12d05bcdf11948c384f699 + Author: Jens Maurer + Date: Mon May 13 23:47:55 2024 +0200 + + [basic.fundamental] Center second column of "integer width" table + + Fixes ISO/CS comment (C++23 proof) + + commit 2a2b8732e0d81dd9f5d3880b70bd451173e5f5fc + Author: Thomas Köppe + Date: Tue Jul 9 15:41:56 2024 +0100 + + [intro.defs] Minor rewording. Avoid sounding like a requirement. + + commit 4746925c7117015480542fd68ad5f595b78173d2 + Author: Jens Maurer + Date: Tue May 14 14:11:53 2024 +0200 + + [numeric.limits.members,bibliography] Remove LIA-1 abbreviation for ISO 10967 + + Fixes ISO/CS comment (C++23 proof) + + commit c18d51ddf436abf39065ea86497161383bba11c0 + Author: Jens Maurer + Date: Wed May 15 09:05:36 2024 +0200 + + [intro.memory] Move footnote about Unicode trademark to [lex.phases] + + Fixes ISO/CS comment (C++23 proof) + + commit 1f32f6aa8000f194f1b5c4daba94d271eea817fb + Author: Jens Maurer + Date: Wed May 15 16:28:34 2024 +0200 + + [diff,bibliography] Move details of old C++ standards to the bibliography + + Fixes ISO/CS comment (C++23 proof) + + commit d5410b4035e3108d48a63434abfff7e377c996d2 + Author: Jens Maurer + Date: Wed May 15 18:31:14 2024 +0200 + + [diff.cpp20,diff.cpp17] Add missing inclusion clause + + commit af4cf904c3d2df0675dbd456af2de2f1259e370c + Author: Jens Maurer + Date: Thu May 16 12:56:12 2024 +0200 + + [std] Rename 'In general' headings to 'General' for consistency + + Fixes ISO/CS comment (C++23 proof) + + commit 9d3011b4224bb63636f4a117967e8ba8110f5ba4 + Author: Jens Maurer + Date: Fri May 17 14:11:48 2024 +0200 + + [implimits] Rephrase introductory sentence for list of quantities + + Fixes ISO/CS comment (C++23 proof) + + commit 260d3a0d0cde1431dd4221115e1b37979ee07e7d + Author: Jens Maurer + Date: Thu May 16 12:30:44 2024 +0200 + + [class.copy.ctor] Remove reference to non-existing example + + Fixes ISO/CS comment (C++23 proof) + + commit 0bc3e030be28ff2191af8e9c9c202bff6e23c320 + Author: Jens Maurer + Date: Thu May 16 12:37:12 2024 +0200 + + [class.conv.general] Remove vague reference to unhelpful examples + + Fixes ISO/CS comment (C++23 proof) + + commit 861f07de24c5cfbd69840038d8589bc13b24b7e7 + Author: Jens Maurer + Date: Wed May 15 21:58:36 2024 +0200 + + [cpp.predefined,namespace.future,version.syn] Replace 'C++' with 'this document' + + Fixes ISO/CS comment (C++23 proof) + + commit a7a2cbd10ea752d49ca286e3fea3e7cbbb9b6e9d + Author: Jens Maurer + Date: Fri May 17 00:44:32 2024 +0200 + + [futures.state] Turn note into example + + Fixes ISO/CS comment (C++23 proof) + + commit 88c48bb78815576fb20db42b89f381c580d28b0e + Author: Jens Maurer + Date: Tue May 14 22:41:24 2024 +0200 + + [std] Remove colons in front of bulleted lists + + commit 9d7aa6108b84a09117463d0b13bc24cf61926897 + Author: Jens Maurer + Date: Tue May 14 22:47:38 2024 +0200 + + [iterators] Add colon after 'model ... only if' when complete sentences follow + + commit 79ac47f7053da4ef20c117e282377591d028e7a5 + Author: Jens Maurer + Date: Wed May 15 21:42:09 2024 +0200 + + [basic.fundamental,cstdarg.syn] Use full reference for ISO C sections + + Fixes ISO/CS comment (C++23) + + commit 2bbf136502811925250b09fd73909b78e0236091 + Author: Jens Maurer + Date: Thu May 16 12:51:32 2024 +0200 + + [execpol.general] Use 'this document', not 'this standard' + + Fixes ISO/CS comment (C++23 proof) + + commit e65393f3c87d323258e38c498b849dc57404a20b + Author: Jens Maurer + Date: Wed May 15 22:13:14 2024 +0200 + + [format.string.std] Add (R) symbol after Windows + + Fixes ISO/CS comment (C++23 proof) + + commit dafefea895de358b8edcb6780e3c7b71d209b458 + Author: Jens Maurer + Date: Tue May 14 19:12:57 2024 +0200 + + [rand.req] Replace 'that Table' with a precise reference + + Fixes ISO/CS comment (C++23 proof) + + commit 361e7769a245aad263574bbe83b9266d8da3b01b + Author: Jens Maurer + Date: Fri May 17 09:42:22 2024 +0200 + + [std] Replace 'this standard' with 'this document' + + Fixes ISO/CS comment (C++23 proof) + + commit e86031dd14e052956fc23ec4dbc1510b7438ba5b + Author: Jens Maurer + Date: Mon May 13 23:19:57 2024 +0200 + + [time.format,time.parse] Fix references to ISO week calendar + + Fixes ISO/CS comment (C++23 proof) + + commit 868b0b29ac16370ed8792442a0ab41be91c5d575 + Author: Jens Maurer + Date: Mon May 13 19:01:05 2024 +0200 + + [std] Avoid hanging paragraphs by introducing "General" subclauses + + Fixes ISO/CS comment (C++23 proof) + + commit f0580700cf0e8e920ceb3a078b6872a4c16fa225 + Author: Jens Maurer + Date: Wed May 15 21:49:31 2024 +0200 + + [std] Remove ISO from any mention of 'C' + + Fixes ISO/CS comment (C++23 proof) + + commit 69f184ea599635dac4cd9dc06a3303bed93b26f7 + Author: Jens Maurer + Date: Mon May 13 19:30:38 2024 +0200 + + [std] Remove mid-sentence 'subclause' introducer + + Fixes ISO/CS comment (C++23 proof) + + commit ecb071672b02a4b7bc829f87433d98785d9dd701 + Author: Jens Maurer + Date: Mon May 13 19:44:40 2024 +0200 + + [std] Remove incorrect or duplicative 'this subclause' introducers + + Fixes ISO/CS comment (C++23 proof) + + commit a249f9f37531fe79e768f19a45f1b1a70685c2c6 + Author: Thomas Köppe + Date: Tue Jul 9 22:48:20 2024 +0100 + + [classes] Turn ad-hoc examples into proper examples (#7125) + + commit eade3851e174ac014b478b8d4f097103d3b996ae + Author: Jens Maurer + Date: Thu May 16 12:44:01 2024 +0200 + + [lex.ccon,expr.prim.lambda.capture] Excise 'ISO' prefix + + Fixes ISO/CS comment (C++23 proof) + + commit 5383169856690cf05d946f058ed861119405d126 + Author: Jens Maurer + Date: Thu May 16 14:32:49 2024 +0200 + + [fs.class.path.general] Defuse cross-reference to POSIX + + Fixes ISO/CS comment (C++23 proof) + + commit 5731ab6a9122763bf6193d1382a05c7bebe82b38 + Author: Thomas Köppe + Date: Tue Jul 9 23:24:09 2024 +0100 + + [time.format] Remove mid-sentence 'subclause' introducer from external reference + + commit 856d175973d343d8e16d641221f47357672d9959 + Author: Jens Maurer + Date: Fri May 17 14:26:54 2024 +0200 + + [lib] Excise Note A, Note B, etc. designations + + Fixes ISO/CS comment (C++23 proof) + + commit 5508a007540d790a8f5cd30f863f4d329edf2694 + Author: Jens Maurer + Date: Thu May 16 15:07:27 2024 +0200 + + [macros,numerics] Add and use numbered 'formula' environment + + Fixes ISO/CS comment (C++23 proof) + + commit 2b0ff8d6bd285bbe8b27fdab47e268b115a3f930 + Author: Thomas Köppe + Date: Wed Jul 10 11:33:23 2024 +0100 + + [lex.string] Replace colon with full stop to end the sentence. + + On request of ISO/CS, for otherwise we should have made the next 'if' + lowercase, because: "Grammatically this is the same sentence, + as there is no full stop, so the 'if' should be lowercase." + + If a colon really doesn't end a sentence, then we should make it so + that the sentence really does end. + + commit 064fb0b34eb8cbb14f52dc966c833ef7c749c82c + Author: Jens Maurer + Date: Tue May 14 08:23:07 2024 +0200 + + [macros] Prefer page break above 'note' or 'example' introducers + + Fixes ISO/CS comment (C++23 proof) + + commit 13b08d0f58dfea7ae2e19b1d931094d4523a52d2 + Author: Thomas Köppe + Date: Thu Jul 11 01:41:29 2024 +0100 + + [layout, styles] New ISO header and footer layout. + + The footer now takes up two lines, one for the copyright and one for + the page number. + + commit 7f6069c794abb56e51affdc2923e3d33b3a547a8 + Author: Thomas Köppe + Date: Thu Jul 11 12:27:28 2024 +0100 + + [cover-reg] Update regular cover + + commit f41a619cf852ae638bfe4792ec78ac1f214a7d23 + Author: Thomas Köppe + Date: Fri Jul 12 01:28:38 2024 +0100 + + [impldefindex] Reinstate full page mark + + As of 13b08d0f58dfea7ae2e19b1d931094d4523a52d2 we have space for it. + + commit b2870b5c87765946f5c4a644da508adcc483045e + Author: Thomas Köppe + Date: Fri Jul 12 01:30:06 2024 +0100 + + [macros, std] Create macros for ISO/IEC 60559 and ISO/IEC/IEEE 9945. + + As a side effect, this corrects the title of ISO/IEC 60559(:2020), + whose previous version was ISO/IEC/IEEE 60559:2011. diff --git a/papers/n4989.html b/papers/n4989.html new file mode 100644 index 0000000000..00eecf259e --- /dev/null +++ b/papers/n4989.html @@ -0,0 +1,569 @@ + + + + + +N4989 Editors’ Report: Programming Languages — C++ + + +

N4989 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-08-05

+ +

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

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

Draft approval

+ +

The previous draft +N4986 +was not approved at any WG21 meeting. For approval of this draft, N4988, +please consult the previous Editors' report +N4987 +as well as this one.

+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All passed motions from CWG and LWG motions 1 through 9 were applied in the previous draft +N4986. +LWG motions 10, 11, and 12 had not yet been applied due to a lack of time, +and are included in this draft.

+ +

The full list of approved motions is included here for ease of reference.

+ +

Core working group polls

+ +

Already applied in previous draft.

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except 2819, 2858, and 2876 in +P3345R0 +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the proposed resolution of issues 2819, 2858, and 2876 in +P3345R0 +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper.

+ +

CWG Poll 3. Apply the changes in +P2747R2 +(constexpr placement new) to the C++ Working Paper.

+ +

CWG Poll 5. Apply the changes in +P3144R2 +(Deleting a Pointer to an Incomplete Type Should be Ill-formed) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in +P2963R3 +(Ordering of constraints involving fold expressions) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in +P0963R3 +(Structured binding declaration as a condition) to the C++ Working Paper.

+ +

CWG Poll 4 did not have consensus.

+ +

Library working group polls

+ +

Already applied in previous draft.

+ +

LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +P3341R0 +(C++ Standard Library Ready Issues to be moved in St. Louis, Jun. 2024) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P2997R1 +(Removing the common reference requirement from the indirectly invocable concepts) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P2389R2 +(dextents Index Type Parameter) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in +P3168R2 +(Give std::optional Range Support) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in +P3217R0 +(Adjoints to "Enabling list-initialization for algorithms": find_last) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in +P2985R0 +(A type trait for detecting virtual base classes) to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in +P0843R14 +(inplace_vector) to the C++ working paper.

+ +

LWG Poll 8. Accept as a Defect Report and apply the changes in +P3235R3 +(std::print more types faster with less memory) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in +P2968R2 +(Make std::ignore a first-class object) to the C++ working paper.

+ +

Newly applied in this draft:

+ +

LWG Poll 10. Apply the changes in +P2075R6 +(Philox as an extension of the C++ RNG engines) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in +P2422R1 +(Remove nodiscard annotations from the standard library specification) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in +P2300R10 +(std::execution) to the C++ working paper.

+ +

Editorial changes

+ +

Major editorial changes

+ +

There were no major editorial changes.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4986 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 a52859fad0d3bc56ec941fc287d5cebc0fd080dc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 12 14:35:07 2024 +0100
+
+    [diff.cpp23.dcl.dcl] Fix capitalisation of heading
+
+commit 811e9bb15fe6b8fe0a6e5584525b7839e329126b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 23 00:19:37 2024 +0100
+
+    [intro.refs] Move footnote
+
+    As requested by ISO/CS.
+
+commit dd306a57cdcce4596fb9d5ce917075eee8e60f4b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 23 00:22:31 2024 +0100
+
+    [intro.races] Rephrase note to avoid awkward "can not".
+
+    Suggested by ISO/CS.
+
+commit 3dc8333128753e8eb4c39f353aa272a63221e6d5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 23 00:28:48 2024 +0100
+
+    [library.c] Clarify that Annex F comes from ISO/IEC 9899:2018
+
+commit b303620f529bfe517fb0c79d3e7f644c54a1e6cb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 23 00:20:42 2024 +0100
+
+    [rand.dist] Remove textual elements from forumla.
+
+    Those were left over from when we converted the text-integrated
+    formula to self-contained, numbered ones.
+
+commit 7228e06a7973282cf1034a9cdb095dd863aef377
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 17 00:48:45 2024 +0100
+
+    [tab:headers.cpp.fs] Use a more appropriate subclause for inplace_vector
+
+commit 3f5771916e846d16330a87df15d35e797ea66437
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 23 17:48:36 2024 -0400
+
+    [depr.c.macros] Cross-reference the C headers for deprecated macros
+
+commit be25cad169c62518e934cd3269e966091b20a4c4
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Jul 22 17:25:04 2024 +0800
+
+    [inplace.vector.syn] Default template argument for `erase`
+
+    The default template argument is already in [inplace.vector.erasure].
+
+commit e0fe4a30614303116dc91357ab1bb483dc98b2ca
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Jul 22 00:24:26 2024 +0800
+
+    [inplace.vector.modifiers] Fix typo
+
+commit 420cff6a620498b6e6b0a4a7f0757bfa8dfb2a1c
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Sun Jul 28 00:05:29 2024 +0800
+
+    [func.search.bm] Remove superfluous the (#7160)
+
+commit cf27216f6aeba4a7e1debed304303fc2e69b2d65
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Jul 22 13:11:05 2024 +0800
+
+    [inplace.vector.erasure] Added missing return statement
+
+commit dc8b2d4d198a307b749832044e2819de1378ace7
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 23 22:28:38 2024 -0400
+
+    [locale.ctype.general] Better cross-ref standard headers
+
+commit f181708d17038c0ebe42aff9d61e79222e5a06b0
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jul 19 20:33:06 2024 +0100
+
+    [basic.indet] Fix "errorneous" typo
+
+commit 1a15d3a3d84549687eb65a870952441c869f31a9
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Jul 28 07:56:03 2024 +0800
+
+    Make cross-reference more precise. (#7144)
+
+    Co-authored-by: Eelis van der Weegen <eelis@eelis.net>
+
+commit 930502061ea47c184c3b25ed623801dfa5284167
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Jul 28 01:57:52 2024 +0200
+
+    [temp.constr.normal] Remove duplicate "the" (#7135)
+
+commit 11e13d5d858f06ec163ece2881af642a23fe5b96
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Jul 28 01:58:09 2024 +0200
+
+    [diff.cpp23.expr] Remove duplicate "that" (#7134)
+
+commit 8ead4680a67cacffe82e2fd74e64df76120cb1a9
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 10 20:28:34 2024 +0800
+
+    [variant.visit] Add constexpr to as-variant
+
+commit 8d8861cdc944b784db14be27ce2541071288dcc5
+Author: A. Jiang <de34@live.cn>
+Date:   Mon May 13 00:33:24 2024 +0800
+
+    [print.syn] Show `locking` functions in the synopsis of `<print>`
+
+commit 5c3858e09e73c49748901aceb33acc7cd86bd7de
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jul 28 13:35:39 2024 +0200
+
+    [exec.snd.general] Add missing period (#7172)
+
+commit 3e87f29c42ad38e224ac6e7e75dc08220b440189
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jul 28 13:37:06 2024 +0200
+
+    [out.ptr.t] Fix bullet placement for item that starts with codeblock (#7173)
+
+commit 81d85dfbee01b8fdf993fac4efeb40fb00b18144
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jul 28 13:39:12 2024 +0200
+
+    [range.concat.iterator] Remove stray hyphen (#7171)
+
+commit 500b8f49f28b51c576eb671ee067efcc1bc002a9
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Jul 28 22:22:54 2024 +0800
+
+    [print.syn] Update `locking` to `buffered` (#7168)
+
+    The function names were changed by P3235R3.
+
+commit 9b3d01e82b03e26cf9e1fa06a582ec931ca00052
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jul 28 21:16:58 2024 +0200
+
+    [execution.syn] Fix read_env name (#7169)
+
+commit 5bac031ccb4f7ce511c6e95b63b39eee2eb14c87
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 27 00:48:42 2024 +0100
+
+    [stoptoken.general, stopsource.general] Remove DMI from stop-state member
+
+    For stoptoken::stop-state, the default-initialized value is already
+    correct, and no further "{}" initializer is needed.
+
+    For stopsource::stop-state, the DMI "{}" is never used, since the
+    constructor is explicitly specified and not defaulted.
+
+commit 917c271c926214e286f560c4a3f2aadc59dadcb7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 27 00:12:22 2024 +0100
+
+    [exec.snd.general] Remove disconnected and obsolete paragraph.
+
+commit 609068d41d699b85b0677fbb206235a4bc30fd77
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jun 8 16:13:36 2024 +0200
+
+    [array.cons] Fix various wording issues
+
+commit f8468b9606aa4db0a55f1ecde046025876c5de23
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Aug 6 21:52:00 2023 +0200
+
+    [expr.cond] itemize p4
+
+commit d9bff4abf4e4de12ef816d3e9df4ed5c6733da64
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Jul 29 23:31:19 2024 +0800
+
+    [coro.generator] Rename the generator's template parameter "V" to "Val" (#7129)
+
+commit aa4a13e9ea6e81e7d2ef5205de9e1f765a27bbbe
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Aug 19 13:33:10 2023 +0200
+
+    [basic.fundamental] itemize uses of void expressions
+
+commit 0711baa8bf611656aae770a6bc23b7ee96ed5811
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Aug 19 13:47:04 2023 +0200
+
+    [basic.fundamental] remove redundant void conversion wording
+
+commit 5342083f2c84f6592c455562d8a6b464d39d86ba
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Jun 17 10:55:22 2024 +0700
+
+    [cpp.pre] define, index, and consistently use the term 'logical source line'
+
+commit 56079f18c4751d4dd15fbdf7d50179d2044345f3
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jan 12 10:35:39 2024 -0800
+
+    [structure.specifications] clarify description of Results element
+
+    The text "... the expression is an lvalue if the type is an lvalue reference type, an xvalue if the type is an rvalue reference type, and a prvalue otherwise" clearly indicates that a Result element describes the type and value category of an expression, yet we summarize it as only "a description of the type of the expression".
+
+commit 407c552023c069afc2438cd462049a323c971bb1
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Jul 16 19:41:36 2024 -0400
+
+    [deque, forward.list, list, vector] Fix instances of "FooInsertable into *this"
+
+    Fixes #7133
+
+commit 4bf5bd233461b49924ea330b95698fdc43cf3636
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Apr 25 00:46:41 2024 +0800
+
+    [alg.replace] Fix misapplication of P2248R8 to `std::replace_copy`
+
+    Removes wrongly added default template arguments that are not present in that paper.
+
+commit d0615b3d8b991fd0cd58fbd6b75da727423cff4e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 23 22:20:27 2024 -0400
+
+    [containers] Consistently xref header synopses from General clauses
+
+commit 35904b92e4bbabd0303f8fb7cbbe3a6142639876
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Apr 27 00:46:29 2024 +0800
+
+    [expr.call] Say implicit object parameter instead of `this`
+
+    And correct the initialization of the implicit object parameter.
+
+commit 7f76c21f933b167d71a1ff12584911e82477454d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jul 29 18:48:49 2024 +0100
+
+    [alg.search] Replace "the following corresponding conditions"
+
+    It's not clear which conditions correspond to each overload.
+
+commit 69ddb6ec0b50c92390391ec54b97c92ef2179869
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 29 21:54:11 2024 +0200
+
+    [exec.stopped.opt] Fix indefinite article (#7186)
+
+commit 4800c7b83d2fbde2c63c6811716bf62df047f5ae
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Jul 30 18:02:17 2024 +0800
+
+    [range.join.with.iterator] Fix typo (#7131)
+
+commit 3dba07b8277a59792430cd166192ed41e428c6f7
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jul 30 12:03:20 2024 +0200
+
+    [exec.util.cmplsig.trans] Fix English grammar (#7188)
+
+commit f640daed4a6304ef4e2c289c6d42e754d06cd4ee
+Author: Anoop Rana <93918384+ranaanoop@users.noreply.github.com>
+Date:   Thu Jul 25 19:57:36 2024 +0530
+
+    [basic.scope.scope] Replaced the term top-level reference with just reference
+
+    [basic.scope.scope] Replaced the term top-level reference with just reference in light of [this issue](https://github.com/cplusplus/CWG/issues/569)
+
+commit 54fb7eb6ada6e7a4d47c9a310675d5cf55bbd5c7
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 30 16:22:02 2024 -0400
+
+    [lex.pptoken] Consistent use of preprocessing vs processing
+
+    There are three cases here all doing the same thing.  Two
+    refer to preprocessing a directive, while the first refers
+    to processing without the pre.
+
+ + diff --git a/papers/n4989.md b/papers/n4989.md new file mode 100644 index 0000000000..6a639a8806 --- /dev/null +++ b/papers/n4989.md @@ -0,0 +1,428 @@ +# N4989 Editors' Report -- Programming Languages -- C++ + +Date: 2024-08-05 + +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 + + * [N4988](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf) is the + current working draft for C++26. It replaces + [N4986](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf). + * N4989 is this Editors' Report. + +## Draft approval + +The previous draft +[N4986](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf) +was not approved at any WG21 meeting. For approval of this draft, N4988, +please consult the previous Editors' report +[N4987](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4987.html) +as well as this one. + +## Motions incorporated into working draft + +### Notes on motions + +All passed motions from CWG and LWG motions 1 through 9 were applied in the previous draft +[N4986](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf). +LWG motions 10, 11, and 12 had not yet been applied due to a lack of time, +and are included in this draft. + +The full list of approved motions is included here for ease of reference. + +### Core working group polls + +**Already applied in previous draft.** + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except 2819, 2858, and 2876 in +[P3345R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3345r0.html) +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the proposed resolution of issues 2819, 2858, and 2876 in +[P3345R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3345r0.html) +(Core Language Working Group "ready" Issues for the June, 2024 meeting) to the C++ Working Paper. + +CWG Poll 3. Apply the changes in +[P2747R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2747r2.html) +(`constexpr` placement new) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in +[P3144R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3144r2.pdf) +(Deleting a Pointer to an Incomplete Type Should be Ill-formed) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in +[P2963R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2963r3.pdf) +(Ordering of constraints involving fold expressions) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in +[P0963R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0963r3.html) +(Structured binding declaration as a condition) to the C++ Working Paper. + +CWG Poll 4 did not have consensus. + +### Library working group polls + +**Already applied in previous draft.** + +LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +[P3341R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3341r0.html) +(C++ Standard Library Ready Issues to be moved in St. Louis, Jun. 2024) to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P2997R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2997r1.html) +(Removing the common reference requirement from the indirectly invocable concepts) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P2389R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2389r2.html) +(`dextents` Index Type Parameter) to the C++ working paper. + +LWG Poll 4. Apply the changes in +[P3168R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3168r2.html) +(Give `std::optional` Range Support) to the C++ working paper. + +LWG Poll 5. Apply the changes in +[P3217R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3217r0.html) +(Adjoints to "Enabling list-initialization for algorithms": `find_last`) to the C++ working paper. + +LWG Poll 6. Apply the changes in +[P2985R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2985r0.html) +(A type trait for detecting virtual base classes) to the C++ working paper. + +LWG Poll 7. Apply the changes in +[P0843R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0843r14.html) +(`inplace_vector`) to the C++ working paper. + +LWG Poll 8. Accept as a Defect Report and apply the changes in +[P3235R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3235r3.html) +(std::print more types faster with less memory) to the C++ working paper. + +LWG Poll 9. Apply the changes in +[P2968R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2968r2.html) +(Make std::ignore a first-class object) to the C++ working paper. + +**Newly applied in this draft:** + +LWG Poll 10. Apply the changes in +[P2075R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2075r6.pdf) +(Philox as an extension of the C++ RNG engines) to the C++ working paper. + +LWG Poll 11. Apply the changes in +[P2422R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2422r1.html) +(Remove nodiscard annotations from the standard library specification) to the C++ working paper. + +LWG Poll 12. Apply the changes in +[P2300R10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html) +(std::execution) to the C++ working paper. + +## Editorial changes + +### Major editorial changes + +There were no major editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4986 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/n4986...n4988). + + commit a52859fad0d3bc56ec941fc287d5cebc0fd080dc + Author: Thomas Köppe + Date: Fri Jul 12 14:35:07 2024 +0100 + + [diff.cpp23.dcl.dcl] Fix capitalisation of heading + + commit 811e9bb15fe6b8fe0a6e5584525b7839e329126b + Author: Thomas Köppe + Date: Tue Jul 23 00:19:37 2024 +0100 + + [intro.refs] Move footnote + + As requested by ISO/CS. + + commit dd306a57cdcce4596fb9d5ce917075eee8e60f4b + Author: Thomas Köppe + Date: Tue Jul 23 00:22:31 2024 +0100 + + [intro.races] Rephrase note to avoid awkward "can not". + + Suggested by ISO/CS. + + commit 3dc8333128753e8eb4c39f353aa272a63221e6d5 + Author: Thomas Köppe + Date: Tue Jul 23 00:28:48 2024 +0100 + + [library.c] Clarify that Annex F comes from ISO/IEC 9899:2018 + + commit b303620f529bfe517fb0c79d3e7f644c54a1e6cb + Author: Thomas Köppe + Date: Tue Jul 23 00:20:42 2024 +0100 + + [rand.dist] Remove textual elements from forumla. + + Those were left over from when we converted the text-integrated + formula to self-contained, numbered ones. + + commit 7228e06a7973282cf1034a9cdb095dd863aef377 + Author: Thomas Köppe + Date: Wed Jul 17 00:48:45 2024 +0100 + + [tab:headers.cpp.fs] Use a more appropriate subclause for inplace_vector + + commit 3f5771916e846d16330a87df15d35e797ea66437 + Author: Alisdair Meredith + Date: Tue Jul 23 17:48:36 2024 -0400 + + [depr.c.macros] Cross-reference the C headers for deprecated macros + + commit be25cad169c62518e934cd3269e966091b20a4c4 + Author: A. Jiang + Date: Mon Jul 22 17:25:04 2024 +0800 + + [inplace.vector.syn] Default template argument for `erase` + + The default template argument is already in [inplace.vector.erasure]. + + commit e0fe4a30614303116dc91357ab1bb483dc98b2ca + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Jul 22 00:24:26 2024 +0800 + + [inplace.vector.modifiers] Fix typo + + commit 420cff6a620498b6e6b0a4a7f0757bfa8dfb2a1c + Author: Hewill Kang + Date: Sun Jul 28 00:05:29 2024 +0800 + + [func.search.bm] Remove superfluous the (#7160) + + commit cf27216f6aeba4a7e1debed304303fc2e69b2d65 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Jul 22 13:11:05 2024 +0800 + + [inplace.vector.erasure] Added missing return statement + + commit dc8b2d4d198a307b749832044e2819de1378ace7 + Author: Alisdair Meredith + Date: Tue Jul 23 22:28:38 2024 -0400 + + [locale.ctype.general] Better cross-ref standard headers + + commit f181708d17038c0ebe42aff9d61e79222e5a06b0 + Author: Jonathan Wakely + Date: Fri Jul 19 20:33:06 2024 +0100 + + [basic.indet] Fix "errorneous" typo + + commit 1a15d3a3d84549687eb65a870952441c869f31a9 + Author: A. Jiang + Date: Sun Jul 28 07:56:03 2024 +0800 + + Make cross-reference more precise. (#7144) + + Co-authored-by: Eelis van der Weegen + + commit 930502061ea47c184c3b25ed623801dfa5284167 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Jul 28 01:57:52 2024 +0200 + + [temp.constr.normal] Remove duplicate "the" (#7135) + + commit 11e13d5d858f06ec163ece2881af642a23fe5b96 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Jul 28 01:58:09 2024 +0200 + + [diff.cpp23.expr] Remove duplicate "that" (#7134) + + commit 8ead4680a67cacffe82e2fd74e64df76120cb1a9 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 10 20:28:34 2024 +0800 + + [variant.visit] Add constexpr to as-variant + + commit 8d8861cdc944b784db14be27ce2541071288dcc5 + Author: A. Jiang + Date: Mon May 13 00:33:24 2024 +0800 + + [print.syn] Show `locking` functions in the synopsis of `` + + commit 5c3858e09e73c49748901aceb33acc7cd86bd7de + Author: Eelis + Date: Sun Jul 28 13:35:39 2024 +0200 + + [exec.snd.general] Add missing period (#7172) + + commit 3e87f29c42ad38e224ac6e7e75dc08220b440189 + Author: Eelis + Date: Sun Jul 28 13:37:06 2024 +0200 + + [out.ptr.t] Fix bullet placement for item that starts with codeblock (#7173) + + commit 81d85dfbee01b8fdf993fac4efeb40fb00b18144 + Author: Eelis + Date: Sun Jul 28 13:39:12 2024 +0200 + + [range.concat.iterator] Remove stray hyphen (#7171) + + commit 500b8f49f28b51c576eb671ee067efcc1bc002a9 + Author: A. Jiang + Date: Sun Jul 28 22:22:54 2024 +0800 + + [print.syn] Update `locking` to `buffered` (#7168) + + The function names were changed by P3235R3. + + commit 9b3d01e82b03e26cf9e1fa06a582ec931ca00052 + Author: Eelis + Date: Sun Jul 28 21:16:58 2024 +0200 + + [execution.syn] Fix read_env name (#7169) + + commit 5bac031ccb4f7ce511c6e95b63b39eee2eb14c87 + Author: Thomas Köppe + Date: Sat Jul 27 00:48:42 2024 +0100 + + [stoptoken.general, stopsource.general] Remove DMI from stop-state member + + For stoptoken::stop-state, the default-initialized value is already + correct, and no further "{}" initializer is needed. + + For stopsource::stop-state, the DMI "{}" is never used, since the + constructor is explicitly specified and not defaulted. + + commit 917c271c926214e286f560c4a3f2aadc59dadcb7 + Author: Thomas Köppe + Date: Sat Jul 27 00:12:22 2024 +0100 + + [exec.snd.general] Remove disconnected and obsolete paragraph. + + commit 609068d41d699b85b0677fbb206235a4bc30fd77 + Author: Eisenwave + Date: Sat Jun 8 16:13:36 2024 +0200 + + [array.cons] Fix various wording issues + + commit f8468b9606aa4db0a55f1ecde046025876c5de23 + Author: Eisenwave + Date: Sun Aug 6 21:52:00 2023 +0200 + + [expr.cond] itemize p4 + + commit d9bff4abf4e4de12ef816d3e9df4ed5c6733da64 + Author: Hewill Kang + Date: Mon Jul 29 23:31:19 2024 +0800 + + [coro.generator] Rename the generator's template parameter "V" to "Val" (#7129) + + commit aa4a13e9ea6e81e7d2ef5205de9e1f765a27bbbe + Author: Eisenwave + Date: Sat Aug 19 13:33:10 2023 +0200 + + [basic.fundamental] itemize uses of void expressions + + commit 0711baa8bf611656aae770a6bc23b7ee96ed5811 + Author: Eisenwave + Date: Sat Aug 19 13:47:04 2023 +0200 + + [basic.fundamental] remove redundant void conversion wording + + commit 5342083f2c84f6592c455562d8a6b464d39d86ba + Author: Alisdair Meredith + Date: Mon Jun 17 10:55:22 2024 +0700 + + [cpp.pre] define, index, and consistently use the term 'logical source line' + + commit 56079f18c4751d4dd15fbdf7d50179d2044345f3 + Author: Casey Carter + Date: Fri Jan 12 10:35:39 2024 -0800 + + [structure.specifications] clarify description of Results element + + The text "... the expression is an lvalue if the type is an lvalue reference type, an xvalue if the type is an rvalue reference type, and a prvalue otherwise" clearly indicates that a Result element describes the type and value category of an expression, yet we summarize it as only "a description of the type of the expression". + + commit 407c552023c069afc2438cd462049a323c971bb1 + Author: Arthur O'Dwyer + Date: Tue Jul 16 19:41:36 2024 -0400 + + [deque, forward.list, list, vector] Fix instances of "FooInsertable into *this" + + Fixes #7133 + + commit 4bf5bd233461b49924ea330b95698fdc43cf3636 + Author: A. Jiang + Date: Thu Apr 25 00:46:41 2024 +0800 + + [alg.replace] Fix misapplication of P2248R8 to `std::replace_copy` + + Removes wrongly added default template arguments that are not present in that paper. + + commit d0615b3d8b991fd0cd58fbd6b75da727423cff4e + Author: Alisdair Meredith + Date: Tue Jul 23 22:20:27 2024 -0400 + + [containers] Consistently xref header synopses from General clauses + + commit 35904b92e4bbabd0303f8fb7cbbe3a6142639876 + Author: A. Jiang + Date: Sat Apr 27 00:46:29 2024 +0800 + + [expr.call] Say implicit object parameter instead of `this` + + And correct the initialization of the implicit object parameter. + + commit 7f76c21f933b167d71a1ff12584911e82477454d + Author: Jonathan Wakely + Date: Mon Jul 29 18:48:49 2024 +0100 + + [alg.search] Replace "the following corresponding conditions" + + It's not clear which conditions correspond to each overload. + + commit 69ddb6ec0b50c92390391ec54b97c92ef2179869 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 29 21:54:11 2024 +0200 + + [exec.stopped.opt] Fix indefinite article (#7186) + + commit 4800c7b83d2fbde2c63c6811716bf62df047f5ae + Author: Hewill Kang + Date: Tue Jul 30 18:02:17 2024 +0800 + + [range.join.with.iterator] Fix typo (#7131) + + commit 3dba07b8277a59792430cd166192ed41e428c6f7 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jul 30 12:03:20 2024 +0200 + + [exec.util.cmplsig.trans] Fix English grammar (#7188) + + commit f640daed4a6304ef4e2c289c6d42e754d06cd4ee + Author: Anoop Rana <93918384+ranaanoop@users.noreply.github.com> + Date: Thu Jul 25 19:57:36 2024 +0530 + + [basic.scope.scope] Replaced the term top-level reference with just reference + + [basic.scope.scope] Replaced the term top-level reference with just reference in light of [this issue](https://github.com/cplusplus/CWG/issues/569) + + commit 54fb7eb6ada6e7a4d47c9a310675d5cf55bbd5c7 + Author: Alisdair Meredith + Date: Tue Jul 30 16:22:02 2024 -0400 + + [lex.pptoken] Consistent use of preprocessing vs processing + + There are three cases here all doing the same thing. Two + refer to preprocessing a directive, while the first refers + to processing without the pre. diff --git a/papers/n4994.html b/papers/n4994.html new file mode 100644 index 0000000000..1778a35243 --- /dev/null +++ b/papers/n4994.html @@ -0,0 +1,737 @@ + + + + + +N4994 Editors’ Report: Programming Languages — C++ + + +

N4994 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-10-16

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

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

Draft approval

+ +

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

+ +

No motions

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

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

+ +

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

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

The new [text] clause obtains the following contents:

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

Additionally, the following subclauses are moved:

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

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

+ +

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

+ +

Minor editorial changes

+ +

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

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

N5002 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-12-17

+ +

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. +Special thanks to Andreas Krug for many timely editorial fixes.

+ +

New papers

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

Motions incorporated into working draft

+ +

Notes on motions

+ +

CWG Poll 9 was retracted.

+ +

Two LWG Polls, Poll 5 (P0472R2) and Poll 17 (P3019R11) have not been applied and +are being sent back to WG21 for clarification. We expect to see revisions to be +approved at the next meeting:

+ +
    +
  • LWG Poll 5 accidentally polled for the obsolete revision P0472R2 instead of the +intended P0472R3. It is sent back due to unclear intentions, with a request for +WG21 to clarify, and the expectation that R3 will be approved.

  • +
  • LWG Poll 17 caused technical discussion after the meeting, in which some +oversights were observed. The paper authors and the LWG chair agreed that +further LWG review would be in everybody's best interest. The poll is sent back +due to unclear specification, with a request for WG21 to produce a revision, +which we expect to be approved at the next meeting.

  • +
+ +

In CWG Poll 1, issue CWG1965 contains no wording changes since it is subsumed by CWG2879.

+ +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +P3524R0 +(Core Language Working Group "ready" Issues for the November, 2024 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the changes in +P3340R0 +(A Consistent Grammar for Sequences) to the C++ Working Paper.

+ +

CWG Poll 3. Apply the changes in +P2686R5 +(constexpr structured bindings and references to constexpr variables) to the C++ Working Paper.

+ +

CWG Poll 4. Apply the changes in +P3068R6 +(Allowing exception throwing in constant-evaluation) to the C++ Working Paper.

+ +

CWG Poll 5. Apply the changes in +P3247R2 +(Deprecate the notion of trivial types) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in +P2865R6 +(Remove Deprecated Array Comparisons from C++26) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in +P1061R10 +(Structured Bindings can introduce a Pack) to the C++ Working Paper.

+ +

CWG Poll 8. Apply the changes in +P3176R1 +(The Oxford variadic comma) to the C++ Working Paper.

+ +

CWG Poll 9 was retracted.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +P3504R0 +(C++ Standard Library Ready Issues to be moved in Wrocław, Nov. 2024) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P3136R1 +(Retiring niebloids) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P3138R5 +(views::cache_latest) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in +P3379R0 +(Constrain std::expected equality operators) to the C++ working paper.

+ +

LWG Poll 5 was sent back (see above).

+ +

LWG Poll 6. Apply the changes in +P2862R1 +(text_encoding::name() should never return null values) to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in +P2897R7 +(aligned_accessor: An mdspan accessor expressing pointer over-alignment) to the C++ working paper.

+ +

LWG Poll 8. Apply the changes in +P3355R1 +(Fix submdspan for C++26) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in +P3222R0 +(Fix C++26 by adding transposed special cases for P2642 layouts) to the C++ working paper.

+ +

LWG Poll 10. Apply the changes in +P3050R2 +(Fix C++26 by optimizing linalg::conjugated for noncomplex value types) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in +P3396R1 +(std::execution wording fixes) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in +P2835R7 +(Expose std::atomic_ref's object address) to the C++ working paper.

+ +

LWG Poll 13. Apply the changes in +P3323R1 +(cv-qualified types in atomic and atomic_ref) to the C++ working paper.

+ +

LWG Poll 14. Apply the changes in +P3508R0 +(Wording for "constexpr for specialized memory algorithms") and +P3369R0 +(constexpr for uninitialized_default_construct) to the C++ working paper.

+ +

LWG Poll 15. Apply the changes in +P3370R1 +(Add new library headers from C23) to the C++ working paper.

+ +

LWG Poll 16. Apply the changes in +P3309R3 +(constexpr atomic and atomic_ref) to the C++ working paper.

+ +

LWG Poll 17 was sent back (see above).

+ +

LWG Poll 18. Apply the changes in +P1928R15 +(std::simd — merge data-parallel types from the Parallelism TS 2) to the C++ working paper.

+ +

LWG Poll 19. Apply the changes in +P3325R5 +(A Utility for Creating Execution Environments) to the C++ working paper.

+ +

Editorial changes

+ +

Major editorial changes

+ +

There have not been any major editorial changes.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4993 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 e9604bcd3d8325860a4db9d02c4f90d0ae70162e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 16 21:12:40 2024 +0100
+
+    [depr.format.syn] Fix header reference
+
+commit 0b296da823e7af4a987a0a870ae299420b9ae502
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Oct 17 00:39:04 2024 +0100
+
+    [{localization,re}.general] Change "This Clause" to "Subclause".
+
+    These subclauses are no longer top-level clauses.
+
+commit 629e10e2f4177dd24d513be71f2203de325a7e8a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Oct 17 08:57:39 2024 +0200
+
+    [inplace.vector.overview] Add missing ',' in comment
+
+commit 726e07a3a99a87f5e89dd40a064f4a6bc84ed3ce
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Oct 17 08:25:55 2024 +0200
+
+    [cpp.subst] Fix typo
+
+commit 88b2b8dcbd145782cfab61e6dad9296c9294593d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 16 22:58:07 2024 +0200
+
+    [exec.domain.default] Add missing \pnum
+
+commit 8698ea48e40acc2e18630e799bbb23c41b9344e6
+Author: James Touton <bekenn@gmail.com>
+Date:   Mon Sep 16 21:47:30 2024 -0700
+
+    [over.match.best.general] Minor formatting fixes
+
+commit 7ad39cbf374764a4e232f967e01541419230fedc
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Oct 17 11:16:28 2024 -0400
+
+    [lex.comment] Move the subclause earlier, to where it better fits
+
+    Comments should fit betweem character sets (to define the basic source
+    character set) and preprocessor tokens, that must already understand
+    comments in order to treat them as whitespace.
+
+commit 7f7170cc9b96e9cc76bc0b765837978856936ab1
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Oct 5 16:21:15 2024 -0400
+
+    [depr] Reorder clauses by origin of deprecation
+
+    Reorders the deprecated features annex to follow the order
+    of the main clauses that the deprecates feature refers to.
+    Where multiple clauses are references, use the one named by
+    the [depr.XXX] stable label.
+
+commit cd21b72788d9066f79f31fb6c4516481dfbb4925
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Oct 18 03:55:20 2024 +0800
+
+    [range.concat.iterator] Remove redundant \expos comments (#6942)
+
+commit 801fb2c0aaf6693a06a9a9e38871bae9536dc194
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Oct 17 17:05:47 2024 -0400
+
+    [lex] Reorder subclauses to better follow phases of translation
+
+    This PR purely moves existing words around, and does not create any new content.
+
+    The proposed subclause ordering is now:
+
+    * 5 Lexical convensions
+      - 5.1 Separate translation
+      - 5.2 Phases of translation
+      - 5.3 Characters
+        - 5.3.1 Character sets
+        - 5.3.2 Universal character names
+      - 5.4 Comments
+      - 5.5 Preprocessing tokens
+      - 5.6 Header names
+      - 5.7 Preprocessing numbers
+      - 5.8 Operators and punctuators
+      - 5.9 Alternative tokens
+      - 5.10 Tokens
+      - 5.11 Identifiers
+      - 5.12 Keywords
+      - 5.13 Literals
+        - 5.13.1 Kinds of literals
+        - 5.13.2 ...
+
+commit 49113a4a577b8d6aed7e5321f0c1fe68d0bd6480
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 18 08:28:28 2024 +0200
+
+    [library.general] Adjust library overview for recent clause restructuring
+
+commit a470ff890be232b9e2a15e44c406ef72c7d816c2
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Oct 19 11:31:59 2024 +0200
+
+    [lex.pptoken] Fix indefinitive article for consistency (#7324)
+
+commit 92594a81f021e76dce6acf7ea5d8176350a1e3fb
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Mar 13 21:04:43 2019 +0100
+
+    [temp.deduct.call] Include surrounding code in math formula
+
+commit 0451d08aefd5318254d7d204ad45700aa4d5a2e7
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Oct 21 19:45:10 2024 +0800
+
+    [specialized.algorithms.general] Restore the note for potentially-overlapping objects and undefined behavior (#7326)
+
+    The original note was incorrect and removed (see #6157). But it turns out
+    that _some_ note is still helpful. This PR tries to find the right way to
+    describe storage reusing and potential subsequent undefined behavior.
+
+commit f6b7ef3f1c6e483d97ad5a4f86b3efed38b74c99
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Oct 19 11:41:35 2024 -0400
+
+    [lex.phases] Add crossreferences from phases 3 and 4
+
+    The phases of translation use forward references to the rest
+    of the standard well, but phases 3 and 4 almost entirely lack
+    such crossreferences, despite doing significant work in the
+    process of translating a file.
+
+commit a69507a54e67ae91424d9c621a9cb57ef3ba1512
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 21 17:48:09 2024 +0200
+
+    [locale.codecvt.virtuals] Fix garbled sentence
+
+commit e0576ed2411f36b0ba648afbf6953a0c72c9effb
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 21 13:09:51 2024 -0400
+
+    [compliance] Sort the freestanding headers after clause reorganization
+
+commit b0135f256e40d45faf1d1ac2aaa3abbda36a17c3
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Oct 22 02:14:47 2024 -0500
+
+    [exec.awaitables] Add missing word (#7340)
+
+commit eb9872aedc581e82e804c0fe8ca7d478ba066b17
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Oct 22 12:09:22 2024 +0200
+
+    [func.wrap.func.con] Fix ill-formed postcondition (#7341)
+
+commit ced2c3866cb3d410c812fa3c359058d185aec329
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 23 13:47:18 2024 -0400
+
+    [allocator.requirements.general] Remove redundant template syntax (#5872)
+
+commit e70d9d6b901457cae9f4f596393f4bf7cee4591a
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Oct 21 20:29:10 2024 +0200
+
+    [intro.races] Clarify conflicts for the case where no bits are changed
+
+commit 6ba0dc9b2bf4c3cebc51154e4d543eafb41a8064
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Aug 20 00:52:57 2023 +0200
+
+    [intro.memory] remove stray definitions
+
+commit 9dc7b3f30d2971ccb3bb38483a7cdb62065a2c3c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 22 17:12:25 2024 -0400
+
+    [basic.stc.inherit] Dissolve paragraph into [...general]
+
+    The whole subclause [basic.stc.inherit] is a single sentence that
+    belongs adjacent to the material in [basic.std.general] that
+    specifies how entities acquire a storage duration, wheras all the
+    remaining subclauses below [basic.stc] describe specific storage
+    durations.  Folding that sentence directly into the general clause
+    is even clearer.
+
+commit d5174d561b61304118cdf1042c5697ec6083c181
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Oct 24 09:03:57 2024 +0200
+
+    [basic.link] Add commas between coordinate subclauses (#7342)
+
+commit 8ab0745b6099fd56288763e57ca47dee099db7cb
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Oct 25 10:53:22 2024 +0200
+
+    [bit.cast] change "behaviour" to "behavior" (#7353)
+
+commit 95d491ed6ca7817423855be4f90b61094a1b4312
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Oct 26 15:52:55 2024 +0200
+
+    [associative.reqmts.general] Fix punctuation (#7354)
+
+commit 3eb8c47d8f2fe050e221b5d4c36189d965273b37
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Oct 26 16:00:12 2024 +0200
+
+    [basic.compound] Add comma to run-on sentence (#7348)
+
+commit 84af20dcd1976a8982d4418756d1ec9728306580
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Oct 27 13:27:34 2024 +0100
+
+    [mdspan.layout.left.cons] Remove duplicate "Effects:" (#7355)
+
+commit ac5b25027266917de3fbb220fc9ecfa4470672f9
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Oct 27 22:46:10 2024 +0100
+
+    [expr.prim.lambda.capture, expr.const, ostream.formatted.print] Reword "automatic variable" (#7358)
+
+commit 324f56439e951773e6ce7437e703fb3aafd5a90c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 28 07:42:45 2024 -0400
+
+    [lex.pptoken] Reorder paragraphs to define terms before they are used (#7346)
+
+    First move p1 below p2, so that we do not refer to preprocessing tokens before they are defined.
+    Then move p4 up, as it is splitting some unrelated examples, neither of which use its contents.
+
+commit bf43925ff0d9e80997918e98989892b4c7bf15f7
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Oct 29 11:52:02 2024 +0100
+
+    [mdspan.layout.left.cons] Fix typo (#7360)
+
+commit a42d1246936f6376acf6188c1b2053886cdaf3c2
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Nov 2 14:38:54 2024 +0100
+
+    [lib.types.movedfrom] Add cross-reference to [defns.valid] (#7365)
+
+commit 6bfbb59e48b6bde05a78d257cbb943acdb2b6781
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Apr 7 17:09:40 2023 +0800
+
+    [format.string.std] Replace "Derived Extracted Property" with simply "property"
+
+commit aa53618e39f16a6fbf147a8ac2d95a33cb8c5cbc
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Aug 9 17:39:07 2024 +0800
+
+    [lex.name] Strike "Derived Core Properties"
+
+commit cb15975d133869eb18a8b7878343a990e63415e2
+Author: Ilya Burylov <burylov@gmail.com>
+Date:   Wed Nov 6 01:44:54 2024 -0800
+
+    [linalg.helpers.mandates] Fix typos (#7372)
+
+commit fcf95f0f1cb3ae11274f1c3477447aadb76b54ca
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Nov 6 13:27:56 2024 +0100
+
+    [exec.opstate.general] Fix typo (#7370)
+
+commit efa0bec63a2718967f7033217a757d536eba3c18
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 6 12:55:52 2024 +0000
+
+    [linalg.reqs.val] Fix use of \defnadjx for value types (#7374)
+
+commit 693835ad625acfdf2d610240b99d6d8fecdb8a6a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Nov 16 06:21:27 2024 -0800
+
+    [fs.op.remove] Clarify "Returns" element (#7387)
+
+    To avoid confusion as in microsoft/STL#5088.
+
+commit 1788b3fcd8f3dbe7b31e6bbfbb968ad43d7ecec3
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Nov 17 20:05:57 2024 +0000
+
+    [over.ics.ref] Fix formatting of 'cv T' (#7389)
+
+commit 16df53c4ab9a17942f5bf994031c98105959a5d5
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Nov 18 17:37:02 2024 +0000
+
+    [defns.regex.primary.equivalence.class] Hyphenate 'locale-specific' (#7395)
+
+commit 4f0facdcd57b922510212ddf44ef39f46dcbe44d
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Nov 18 17:38:09 2024 +0000
+
+    [temp.param] Fix typos (#7394)
+
+commit 99deb7022614be47cfcce4f003d8eb57c02b6926
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Nov 19 05:21:45 2024 +0000
+
+    [over.ics.ref] Capitalize 'Exact Match' (#7392)
+
+commit fb8036b6dfe5ce4a99cd85fddac3f115a7fd96af
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Nov 19 05:25:41 2024 +0000
+
+    [class] Avoid hyphenation for 'multidimensional' (#7391)
+
+commit 3f41cf86547b77854abddde7dcaddf2ff00405bf
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Nov 19 05:26:53 2024 +0000
+
+    [lex.phases] Move cross-reference to the first use of the referenced term (#7393)
+
+commit a05b963e9fe12a8589502b4fbc951c119ae1b3b2
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 30 16:51:21 2024 -0400
+
+    [basic.life] Move definition of before and after from bottom to top of subclause
+
+    The last paragraph of this subclause changes the definition of English words
+    used throughout the preceding paragraphs.  While it might be preferable
+    to replace all such usage with the new definitions, that would be a Core issue,
+    see paragraph 6 for an example of awkward usage.  Hence, we move the
+    redefinition to the start of the subclause so we know how to read this text
+    from the start.
+
+commit 2981bd94f25ea2199fd6b8af7aa76e03cf427697
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Oct 19 08:31:08 2024 -0400
+
+    [basic.align] Move the Alignment subclause adjacent to "Object model"
+
+    Alignment puts additional restrictions on object placement.
+
+commit eac0893a9a90a5704deef6db3deecae026f04271
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Oct 2 14:59:41 2024 -0400
+
+    [except.terminate] Better describe the  function
+
+    While 'std:terminate' was originally conceived as the way to
+    report failures in the exception handling machinery, it has
+    evolved to become a more general tool for reporting unrecoverable
+    failures in the C++ runtime.  This rewording attempts to address
+    that evolving design, and in doing so addresses the outstanding
+    %FIXME% that the current text is not adequately descriptive in
+    the first place.
+
+commit f4c4c7cdfb7fba0a6ffbf8e55f2ea6debdf13e87
+Author: xmh0511 <970252187@qq.com>
+Date:   Wed Nov 20 08:17:02 2024 +0800
+
+    [dcl.link] Change "objects" to "entities"
+
+    "Entities" is more appropriate since it includes functions.
+
+commit 38461e17588aff3c6851de6ffc7f3e89418e0e65
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 7 18:50:10 2024 +0800
+
+    [reverse.iter.cons] Removed redundant wording
+
+commit 8caa49a8266d7ef6b4ef3132588d154de07bbabd
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Mar 1 20:49:37 2024 +0100
+
+    [rand.req.seedseq] Remove 'compile-time' complexity for typedefs
+
+commit e2ddc7ab689bdaf91d2b2aa6424cef2510d3677a
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Mar 1 20:50:27 2024 +0100
+
+    [rand.req.dist] Remove 'compile-time' complexity for typedefs
+
+commit c9155b214a51d069cf4a575f10af2b4c4caca5d7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Mar 1 20:52:39 2024 +0100
+
+    [char.traits.require] Remove 'compile-time' complexity for typedefs
+
+commit 2cd11c5503e78251c0c0fb4147e2d8ccb0947727
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Tue Oct 8 15:30:13 2024 +0400
+
+    [temp.pre] Fix note about uniqueness of a template name in a scope
+
+commit 2edf50afeec8cf200504718646b2b12492dac8ec
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 21 08:33:19 2024 -0400
+
+    [lex.header] Modernize text around header names
+
+    The footnote better belongs in the main text as a regular note.
+    To make the notes flow consistently, switch the order of the
+    note and normative text in the first paragraph to lead with the
+    normative text.
+
+commit 4a5d988a24f6c9737ca076e790b05e22ba169a7a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Nov 22 12:55:43 2024 +0100
+
+    [refwrap.invoke] Place period at end (#7402)
+
+commit aed97568c63ad5c3c200eff34799413f3ad842f4
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Nov 23 07:53:16 2024 +0100
+
+    [lex.ccon, except.spec] Remove extraneous trailing linebreaks (#7403)
+
+commit 219b959258b6314a3c96bee86b8a18b0f4a7c37e
+Author: mrussoLuxoft <117848841+mrussoLuxoft@users.noreply.github.com>
+Date:   Sat Nov 30 19:36:56 2024 +0100
+
+    [dcl.spec.auto.general] Clarify sentence structure by adding bullets (#7450)
+
+commit 861071a824419b955c4efb2d07980e78c9fc62c7
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Wed Dec 4 15:05:03 2024 +0100
+
+    [iterator.requirements.general] Revert `indirectly_writable` to "writable" definition (#7471)
+
+    This fixes a misapplication of the 2019 Belfast meeting LWG motion 9 (P1878R1), which erroneously replaced the "writable" definition by the `indirectly_writable` concept.
+
+commit c530fd8e0f80029e88b0977bebbf70252d38795e
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Dec 6 21:52:45 2024 +0800
+
+    [text.encoding.overview] Add cross-reference text_encoding​::​aliases_view (#7476)
+
+commit 10668dceb8186d7990ff4966a6808bb20ba3eed7
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 12 18:47:14 2024 +0000
+
+    [vector.overview,vector.bool.pspc] Move`at() const` to after `at()` (#7484)
+
+    This is consistent with the ordering for operator[].
+
+commit 0b1256638ebf4f1c611c3ca6182bad69be4837ce
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 16 19:53:51 2024 +0100
+
+    [unique.ptr.single.general] Fix typo
+
+commit 76465d7e42f56f763901e3f6a79ae6d77162a510
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 16 12:17:46 2024 +0100
+
+    [expr.type] Fix typo
+
+commit c7fbd5974f4b5e8881d1dc3e8fdf0b59ecba3bab
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Dec 8 07:34:44 2024 +0800
+
+    [locale.ctype.virtuals] Fix a decade-old typo
+
+commit f9c835be8299556ae5943dbb340b4929a6100b15
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 6 16:51:49 2024 +0100
+
+    [except.spec] Remove misleading restriction in list of examples
+
+commit e99e78d67b631fbb328770fbcd4882e683360cb1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 6 10:57:01 2024 +0100
+
+    [basic.pre,basic.lookup.general] Cleanup definition of term 'name lookup'
+
+commit 57ba5a5f4095ec3df6292cfdc371f554e8b684ef
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Dec 17 12:25:26 2024 -0500
+
+    [lex.phases] Reorder the first two sentences of phase 7 (#7432)
+
+    Currently, the first sentence refers to "tokens" that do not exist until after the second sentence.
+
+commit 55a58f9206e41a831c664747dbacebd25c01b034
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Dec 17 19:34:54 2024 +0100
+
+    [class.conv.ctor] Turn last paragraph into a note (#6505)
+
+commit 3443cd8af21845e5a4fda6246c4c1bbc74cd007b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Dec 17 19:18:25 2024 +0100
+
+    [exec.envs] Fix typo
+
+commit 14199aed5adb4baaef28245b4de88e7ffe73a365
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Dec 17 20:02:55 2024 +0100
+
+    [atomics.ref.int, atomics.ref.float] Minor \tcode fixes (#7499)
+
+commit daae8f9a9b959c099e99f248324af95bbaf11779
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Dec 18 03:09:10 2024 +0800
+
+    [flat.{map,multimap,set,multiset}] Exposition-only formatting (#6404)
+
+commit 7cbd07c13063b9730d51385198e13bb036d40377
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 16 11:08:10 2024 +0100
+
+    [depr.meta.types] Remove superfluous period
+
+commit 7fe908fa11ad69138975bfec2cf376c66a536d08
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Dec 17 14:13:02 2024 -0500
+
+    [cpp] Distinguish "preprocessing token" from "token" (#7482)
+
+commit 9c9d19f6aef145cf2c074dcdd343e7a2446417a9
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Dec 6 17:37:05 2024 +0000
+
+    [sequence.reqmts] Remove unnecessary qualification of which new element
+
+    There is only one new element, and this avoids having to decide whether it should say args....
+
+ + diff --git a/papers/n5002.md b/papers/n5002.md new file mode 100644 index 0000000000..f5c5e576b1 --- /dev/null +++ b/papers/n5002.md @@ -0,0 +1,697 @@ +# N5002 Editors' Report -- Programming Languages -- C++ + +Date: 2024-12-17 + +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. +Special thanks to Andreas Krug for many timely editorial fixes. + +## New papers + + * [N5001](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n5001.pdf) is the + current working draft for C++26. It replaces + [N4993](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4993.pdf). + * N5002 is this Editors' Report. + + +## Motions incorporated into working draft + +### Notes on motions + +CWG Poll 9 was retracted. + +Two LWG Polls, Poll 5 (P0472R2) and Poll 17 (P3019R11) have not been applied and +are being sent back to WG21 for clarification. We expect to see revisions to be +approved at the next meeting: + +* LWG Poll 5 accidentally polled for the obsolete revision P0472R2 instead of the + intended P0472R3. It is sent back due to unclear intentions, with a request for + WG21 to clarify, and the expectation that R3 will be approved. + +* LWG Poll 17 caused technical discussion after the meeting, in which some + oversights were observed. The paper authors and the LWG chair agreed that + further LWG review would be in everybody's best interest. The poll is sent back + due to unclear specification, with a request for WG21 to produce a revision, + which we expect to be approved at the next meeting. + +In CWG Poll 1, issue CWG1965 contains no wording changes since it is subsumed by CWG2879. + +### Core working group polls +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +[P3524R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3524r0.html) +(Core Language Working Group "ready" Issues for the November, 2024 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the changes in +[P3340R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3340r0.pdf) +(A Consistent Grammar for Sequences) to the C++ Working Paper. + +CWG Poll 3. Apply the changes in +[P2686R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2686r5.pdf) +(constexpr structured bindings and references to constexpr variables) to the C++ Working Paper. + +CWG Poll 4. Apply the changes in +[P3068R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3068r6.html) +(Allowing exception throwing in constant-evaluation) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in +[P3247R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3247r2.html) +(Deprecate the notion of trivial types) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in +[P2865R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2865r6.pdf) +(Remove Deprecated Array Comparisons from C++26) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in +[P1061R10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1061r10.html) +(Structured Bindings can introduce a Pack) to the C++ Working Paper. + +CWG Poll 8. Apply the changes in +[P3176R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3176r1.html) +(The Oxford variadic comma) to the C++ Working Paper. + +CWG Poll 9 was retracted. + +### Library working group polls + +LWG Poll 1. Apply the changes for all Ready and Tentatively Ready issues in +[P3504R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3504r0.html) +(C++ Standard Library Ready Issues to be moved in Wrocław, Nov. 2024) to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P3136R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3136r1.html) +(Retiring niebloids) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P3138R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3138r5.html) +(`views::cache_latest`) to the C++ working paper. + +LWG Poll 4. Apply the changes in +[P3379R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3379r0.html) +(Constrain `std::expected` equality operators) to the C++ working paper. + +LWG Poll 5 was sent back (see above). + +LWG Poll 6. Apply the changes in +[P2862R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2862r1.html) +(`text_encoding::name()` should never return null values) to the C++ working paper. + +LWG Poll 7. Apply the changes in +[P2897R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2897r7.html) +(`aligned_accessor`: An `mdspan` accessor expressing pointer over-alignment) to the C++ working paper. + +LWG Poll 8. Apply the changes in +[P3355R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3355r1.html) +(Fix `submdspan` for C++26) to the C++ working paper. + +LWG Poll 9. Apply the changes in +[P3222R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3222r0.html) +(Fix C++26 by adding transposed special cases for P2642 layouts) to the C++ working paper. + +LWG Poll 10. Apply the changes in +[P3050R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3050r2.html) +(Fix C++26 by optimizing `linalg::conjugated` for noncomplex value types) to the C++ working paper. + +LWG Poll 11. Apply the changes in +[P3396R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3396r1.html) +(`std::execution` wording fixes) to the C++ working paper. + +LWG Poll 12. Apply the changes in +[P2835R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2835r7.html) +(Expose `std::atomic_ref`'s object address) to the C++ working paper. + +LWG Poll 13. Apply the changes in +[P3323R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3323r1.html) +(cv-qualified types in `atomic` and `atomic_ref`) to the C++ working paper. + +LWG Poll 14. Apply the changes in +[P3508R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3508r0.html) +(Wording for "constexpr for specialized memory algorithms") and +[P3369R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3369r0.html) +(`constexpr` for `uninitialized_default_construct`) to the C++ working paper. + +LWG Poll 15. Apply the changes in +[P3370R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3370r1.html) +(Add new library headers from C23) to the C++ working paper. + +LWG Poll 16. Apply the changes in +[P3309R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3309r3.html) +(constexpr `atomic` and `atomic_ref`) to the C++ working paper. + +LWG Poll 17 was sent back (see above). + +LWG Poll 18. Apply the changes in +[P1928R15](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1928r15.pdf) +(`std::simd` — merge data-parallel types from the Parallelism TS 2) to the C++ working paper. + +LWG Poll 19. Apply the changes in +[P3325R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3325r5.html) +(A Utility for Creating Execution Environments) to the C++ working paper. + +## Editorial changes + +### Major editorial changes + +There have not been any major editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4993 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/n4993...n5001). + + commit e9604bcd3d8325860a4db9d02c4f90d0ae70162e + Author: Thomas Köppe + Date: Wed Oct 16 21:12:40 2024 +0100 + + [depr.format.syn] Fix header reference + + commit 0b296da823e7af4a987a0a870ae299420b9ae502 + Author: Thomas Köppe + Date: Thu Oct 17 00:39:04 2024 +0100 + + [{localization,re}.general] Change "This Clause" to "Subclause". + + These subclauses are no longer top-level clauses. + + commit 629e10e2f4177dd24d513be71f2203de325a7e8a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Oct 17 08:57:39 2024 +0200 + + [inplace.vector.overview] Add missing ',' in comment + + commit 726e07a3a99a87f5e89dd40a064f4a6bc84ed3ce + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Oct 17 08:25:55 2024 +0200 + + [cpp.subst] Fix typo + + commit 88b2b8dcbd145782cfab61e6dad9296c9294593d + Author: Jens Maurer + Date: Wed Oct 16 22:58:07 2024 +0200 + + [exec.domain.default] Add missing \pnum + + commit 8698ea48e40acc2e18630e799bbb23c41b9344e6 + Author: James Touton + Date: Mon Sep 16 21:47:30 2024 -0700 + + [over.match.best.general] Minor formatting fixes + + commit 7ad39cbf374764a4e232f967e01541419230fedc + Author: Alisdair Meredith + Date: Thu Oct 17 11:16:28 2024 -0400 + + [lex.comment] Move the subclause earlier, to where it better fits + + Comments should fit betweem character sets (to define the basic source + character set) and preprocessor tokens, that must already understand + comments in order to treat them as whitespace. + + commit 7f7170cc9b96e9cc76bc0b765837978856936ab1 + Author: Alisdair Meredith + Date: Sat Oct 5 16:21:15 2024 -0400 + + [depr] Reorder clauses by origin of deprecation + + Reorders the deprecated features annex to follow the order + of the main clauses that the deprecates feature refers to. + Where multiple clauses are references, use the one named by + the [depr.XXX] stable label. + + commit cd21b72788d9066f79f31fb6c4516481dfbb4925 + Author: Hewill Kang + Date: Fri Oct 18 03:55:20 2024 +0800 + + [range.concat.iterator] Remove redundant \expos comments (#6942) + + commit 801fb2c0aaf6693a06a9a9e38871bae9536dc194 + Author: Alisdair Meredith + Date: Thu Oct 17 17:05:47 2024 -0400 + + [lex] Reorder subclauses to better follow phases of translation + + This PR purely moves existing words around, and does not create any new content. + + The proposed subclause ordering is now: + + * 5 Lexical convensions + - 5.1 Separate translation + - 5.2 Phases of translation + - 5.3 Characters + - 5.3.1 Character sets + - 5.3.2 Universal character names + - 5.4 Comments + - 5.5 Preprocessing tokens + - 5.6 Header names + - 5.7 Preprocessing numbers + - 5.8 Operators and punctuators + - 5.9 Alternative tokens + - 5.10 Tokens + - 5.11 Identifiers + - 5.12 Keywords + - 5.13 Literals + - 5.13.1 Kinds of literals + - 5.13.2 ... + + commit 49113a4a577b8d6aed7e5321f0c1fe68d0bd6480 + Author: Jens Maurer + Date: Fri Oct 18 08:28:28 2024 +0200 + + [library.general] Adjust library overview for recent clause restructuring + + commit a470ff890be232b9e2a15e44c406ef72c7d816c2 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Oct 19 11:31:59 2024 +0200 + + [lex.pptoken] Fix indefinitive article for consistency (#7324) + + commit 92594a81f021e76dce6acf7ea5d8176350a1e3fb + Author: Eelis van der Weegen + Date: Wed Mar 13 21:04:43 2019 +0100 + + [temp.deduct.call] Include surrounding code in math formula + + commit 0451d08aefd5318254d7d204ad45700aa4d5a2e7 + Author: A. Jiang + Date: Mon Oct 21 19:45:10 2024 +0800 + + [specialized.algorithms.general] Restore the note for potentially-overlapping objects and undefined behavior (#7326) + + The original note was incorrect and removed (see #6157). But it turns out + that _some_ note is still helpful. This PR tries to find the right way to + describe storage reusing and potential subsequent undefined behavior. + + commit f6b7ef3f1c6e483d97ad5a4f86b3efed38b74c99 + Author: Alisdair Meredith + Date: Sat Oct 19 11:41:35 2024 -0400 + + [lex.phases] Add crossreferences from phases 3 and 4 + + The phases of translation use forward references to the rest + of the standard well, but phases 3 and 4 almost entirely lack + such crossreferences, despite doing significant work in the + process of translating a file. + + commit a69507a54e67ae91424d9c621a9cb57ef3ba1512 + Author: Jens Maurer + Date: Mon Oct 21 17:48:09 2024 +0200 + + [locale.codecvt.virtuals] Fix garbled sentence + + commit e0576ed2411f36b0ba648afbf6953a0c72c9effb + Author: Alisdair Meredith + Date: Mon Oct 21 13:09:51 2024 -0400 + + [compliance] Sort the freestanding headers after clause reorganization + + commit b0135f256e40d45faf1d1ac2aaa3abbda36a17c3 + Author: timsong-cpp + Date: Tue Oct 22 02:14:47 2024 -0500 + + [exec.awaitables] Add missing word (#7340) + + commit eb9872aedc581e82e804c0fe8ca7d478ba066b17 + Author: Jan Schultke + Date: Tue Oct 22 12:09:22 2024 +0200 + + [func.wrap.func.con] Fix ill-formed postcondition (#7341) + + commit ced2c3866cb3d410c812fa3c359058d185aec329 + Author: Alisdair Meredith + Date: Wed Oct 23 13:47:18 2024 -0400 + + [allocator.requirements.general] Remove redundant template syntax (#5872) + + commit e70d9d6b901457cae9f4f596393f4bf7cee4591a + Author: Eisenwave + Date: Mon Oct 21 20:29:10 2024 +0200 + + [intro.races] Clarify conflicts for the case where no bits are changed + + commit 6ba0dc9b2bf4c3cebc51154e4d543eafb41a8064 + Author: Eisenwave + Date: Sun Aug 20 00:52:57 2023 +0200 + + [intro.memory] remove stray definitions + + commit 9dc7b3f30d2971ccb3bb38483a7cdb62065a2c3c + Author: Alisdair Meredith + Date: Tue Oct 22 17:12:25 2024 -0400 + + [basic.stc.inherit] Dissolve paragraph into [...general] + + The whole subclause [basic.stc.inherit] is a single sentence that + belongs adjacent to the material in [basic.std.general] that + specifies how entities acquire a storage duration, wheras all the + remaining subclauses below [basic.stc] describe specific storage + durations. Folding that sentence directly into the general clause + is even clearer. + + commit d5174d561b61304118cdf1042c5697ec6083c181 + Author: Jan Schultke + Date: Thu Oct 24 09:03:57 2024 +0200 + + [basic.link] Add commas between coordinate subclauses (#7342) + + commit 8ab0745b6099fd56288763e57ca47dee099db7cb + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Oct 25 10:53:22 2024 +0200 + + [bit.cast] change "behaviour" to "behavior" (#7353) + + commit 95d491ed6ca7817423855be4f90b61094a1b4312 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Oct 26 15:52:55 2024 +0200 + + [associative.reqmts.general] Fix punctuation (#7354) + + commit 3eb8c47d8f2fe050e221b5d4c36189d965273b37 + Author: Jan Schultke + Date: Sat Oct 26 16:00:12 2024 +0200 + + [basic.compound] Add comma to run-on sentence (#7348) + + commit 84af20dcd1976a8982d4418756d1ec9728306580 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Oct 27 13:27:34 2024 +0100 + + [mdspan.layout.left.cons] Remove duplicate "Effects:" (#7355) + + commit ac5b25027266917de3fbb220fc9ecfa4470672f9 + Author: Jan Schultke + Date: Sun Oct 27 22:46:10 2024 +0100 + + [expr.prim.lambda.capture, expr.const, ostream.formatted.print] Reword "automatic variable" (#7358) + + commit 324f56439e951773e6ce7437e703fb3aafd5a90c + Author: Alisdair Meredith + Date: Mon Oct 28 07:42:45 2024 -0400 + + [lex.pptoken] Reorder paragraphs to define terms before they are used (#7346) + + First move p1 below p2, so that we do not refer to preprocessing tokens before they are defined. + Then move p4 up, as it is splitting some unrelated examples, neither of which use its contents. + + commit bf43925ff0d9e80997918e98989892b4c7bf15f7 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Oct 29 11:52:02 2024 +0100 + + [mdspan.layout.left.cons] Fix typo (#7360) + + commit a42d1246936f6376acf6188c1b2053886cdaf3c2 + Author: Jan Schultke + Date: Sat Nov 2 14:38:54 2024 +0100 + + [lib.types.movedfrom] Add cross-reference to [defns.valid] (#7365) + + commit 6bfbb59e48b6bde05a78d257cbb943acdb2b6781 + Author: S. B. Tam + Date: Fri Apr 7 17:09:40 2023 +0800 + + [format.string.std] Replace "Derived Extracted Property" with simply "property" + + commit aa53618e39f16a6fbf147a8ac2d95a33cb8c5cbc + Author: S. B. Tam + Date: Fri Aug 9 17:39:07 2024 +0800 + + [lex.name] Strike "Derived Core Properties" + + commit cb15975d133869eb18a8b7878343a990e63415e2 + Author: Ilya Burylov + Date: Wed Nov 6 01:44:54 2024 -0800 + + [linalg.helpers.mandates] Fix typos (#7372) + + commit fcf95f0f1cb3ae11274f1c3477447aadb76b54ca + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Nov 6 13:27:56 2024 +0100 + + [exec.opstate.general] Fix typo (#7370) + + commit efa0bec63a2718967f7033217a757d536eba3c18 + Author: Jonathan Wakely + Date: Wed Nov 6 12:55:52 2024 +0000 + + [linalg.reqs.val] Fix use of \defnadjx for value types (#7374) + + commit 693835ad625acfdf2d610240b99d6d8fecdb8a6a + Author: Casey Carter + Date: Sat Nov 16 06:21:27 2024 -0800 + + [fs.op.remove] Clarify "Returns" element (#7387) + + To avoid confusion as in microsoft/STL#5088. + + commit 1788b3fcd8f3dbe7b31e6bbfbb968ad43d7ecec3 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Nov 17 20:05:57 2024 +0000 + + [over.ics.ref] Fix formatting of 'cv T' (#7389) + + commit 16df53c4ab9a17942f5bf994031c98105959a5d5 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Nov 18 17:37:02 2024 +0000 + + [defns.regex.primary.equivalence.class] Hyphenate 'locale-specific' (#7395) + + commit 4f0facdcd57b922510212ddf44ef39f46dcbe44d + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Nov 18 17:38:09 2024 +0000 + + [temp.param] Fix typos (#7394) + + commit 99deb7022614be47cfcce4f003d8eb57c02b6926 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Nov 19 05:21:45 2024 +0000 + + [over.ics.ref] Capitalize 'Exact Match' (#7392) + + commit fb8036b6dfe5ce4a99cd85fddac3f115a7fd96af + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Nov 19 05:25:41 2024 +0000 + + [class] Avoid hyphenation for 'multidimensional' (#7391) + + commit 3f41cf86547b77854abddde7dcaddf2ff00405bf + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Nov 19 05:26:53 2024 +0000 + + [lex.phases] Move cross-reference to the first use of the referenced term (#7393) + + commit a05b963e9fe12a8589502b4fbc951c119ae1b3b2 + Author: Alisdair Meredith + Date: Tue Jul 30 16:51:21 2024 -0400 + + [basic.life] Move definition of before and after from bottom to top of subclause + + The last paragraph of this subclause changes the definition of English words + used throughout the preceding paragraphs. While it might be preferable + to replace all such usage with the new definitions, that would be a Core issue, + see paragraph 6 for an example of awkward usage. Hence, we move the + redefinition to the start of the subclause so we know how to read this text + from the start. + + commit 2981bd94f25ea2199fd6b8af7aa76e03cf427697 + Author: Alisdair Meredith + Date: Sat Oct 19 08:31:08 2024 -0400 + + [basic.align] Move the Alignment subclause adjacent to "Object model" + + Alignment puts additional restrictions on object placement. + + commit eac0893a9a90a5704deef6db3deecae026f04271 + Author: Alisdair Meredith + Date: Wed Oct 2 14:59:41 2024 -0400 + + [except.terminate] Better describe the function + + While 'std:terminate' was originally conceived as the way to + report failures in the exception handling machinery, it has + evolved to become a more general tool for reporting unrecoverable + failures in the C++ runtime. This rewording attempts to address + that evolving design, and in doing so addresses the outstanding + %FIXME% that the current text is not adequately descriptive in + the first place. + + commit f4c4c7cdfb7fba0a6ffbf8e55f2ea6debdf13e87 + Author: xmh0511 <970252187@qq.com> + Date: Wed Nov 20 08:17:02 2024 +0800 + + [dcl.link] Change "objects" to "entities" + + "Entities" is more appropriate since it includes functions. + + commit 38461e17588aff3c6851de6ffc7f3e89418e0e65 + Author: A. Jiang + Date: Thu Nov 7 18:50:10 2024 +0800 + + [reverse.iter.cons] Removed redundant wording + + commit 8caa49a8266d7ef6b4ef3132588d154de07bbabd + Author: Eisenwave + Date: Fri Mar 1 20:49:37 2024 +0100 + + [rand.req.seedseq] Remove 'compile-time' complexity for typedefs + + commit e2ddc7ab689bdaf91d2b2aa6424cef2510d3677a + Author: Eisenwave + Date: Fri Mar 1 20:50:27 2024 +0100 + + [rand.req.dist] Remove 'compile-time' complexity for typedefs + + commit c9155b214a51d069cf4a575f10af2b4c4caca5d7 + Author: Eisenwave + Date: Fri Mar 1 20:52:39 2024 +0100 + + [char.traits.require] Remove 'compile-time' complexity for typedefs + + commit 2cd11c5503e78251c0c0fb4147e2d8ccb0947727 + Author: Vlad Serebrennikov + Date: Tue Oct 8 15:30:13 2024 +0400 + + [temp.pre] Fix note about uniqueness of a template name in a scope + + commit 2edf50afeec8cf200504718646b2b12492dac8ec + Author: Alisdair Meredith + Date: Mon Oct 21 08:33:19 2024 -0400 + + [lex.header] Modernize text around header names + + The footnote better belongs in the main text as a regular note. + To make the notes flow consistently, switch the order of the + note and normative text in the first paragraph to lead with the + normative text. + + commit 4a5d988a24f6c9737ca076e790b05e22ba169a7a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Nov 22 12:55:43 2024 +0100 + + [refwrap.invoke] Place period at end (#7402) + + commit aed97568c63ad5c3c200eff34799413f3ad842f4 + Author: Alisdair Meredith + Date: Sat Nov 23 07:53:16 2024 +0100 + + [lex.ccon, except.spec] Remove extraneous trailing linebreaks (#7403) + + commit 219b959258b6314a3c96bee86b8a18b0f4a7c37e + Author: mrussoLuxoft <117848841+mrussoLuxoft@users.noreply.github.com> + Date: Sat Nov 30 19:36:56 2024 +0100 + + [dcl.spec.auto.general] Clarify sentence structure by adding bullets (#7450) + + commit 861071a824419b955c4efb2d07980e78c9fc62c7 + Author: Daniel Krügler + Date: Wed Dec 4 15:05:03 2024 +0100 + + [iterator.requirements.general] Revert `indirectly_writable` to "writable" definition (#7471) + + This fixes a misapplication of the 2019 Belfast meeting LWG motion 9 (P1878R1), which erroneously replaced the "writable" definition by the `indirectly_writable` concept. + + commit c530fd8e0f80029e88b0977bebbf70252d38795e + Author: Hewill Kang + Date: Fri Dec 6 21:52:45 2024 +0800 + + [text.encoding.overview] Add cross-reference text_encoding​::​aliases_view (#7476) + + commit 10668dceb8186d7990ff4966a6808bb20ba3eed7 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 12 18:47:14 2024 +0000 + + [vector.overview,vector.bool.pspc] Move`at() const` to after `at()` (#7484) + + This is consistent with the ordering for operator[]. + + commit 0b1256638ebf4f1c611c3ca6182bad69be4837ce + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 16 19:53:51 2024 +0100 + + [unique.ptr.single.general] Fix typo + + commit 76465d7e42f56f763901e3f6a79ae6d77162a510 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 16 12:17:46 2024 +0100 + + [expr.type] Fix typo + + commit c7fbd5974f4b5e8881d1dc3e8fdf0b59ecba3bab + Author: S. B. Tam + Date: Sun Dec 8 07:34:44 2024 +0800 + + [locale.ctype.virtuals] Fix a decade-old typo + + commit f9c835be8299556ae5943dbb340b4929a6100b15 + Author: Jens Maurer + Date: Fri Dec 6 16:51:49 2024 +0100 + + [except.spec] Remove misleading restriction in list of examples + + commit e99e78d67b631fbb328770fbcd4882e683360cb1 + Author: Jens Maurer + Date: Fri Dec 6 10:57:01 2024 +0100 + + [basic.pre,basic.lookup.general] Cleanup definition of term 'name lookup' + + commit 57ba5a5f4095ec3df6292cfdc371f554e8b684ef + Author: Alisdair Meredith + Date: Tue Dec 17 12:25:26 2024 -0500 + + [lex.phases] Reorder the first two sentences of phase 7 (#7432) + + Currently, the first sentence refers to "tokens" that do not exist until after the second sentence. + + commit 55a58f9206e41a831c664747dbacebd25c01b034 + Author: Jan Schultke + Date: Tue Dec 17 19:34:54 2024 +0100 + + [class.conv.ctor] Turn last paragraph into a note (#6505) + + commit 3443cd8af21845e5a4fda6246c4c1bbc74cd007b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Dec 17 19:18:25 2024 +0100 + + [exec.envs] Fix typo + + commit 14199aed5adb4baaef28245b4de88e7ffe73a365 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Dec 17 20:02:55 2024 +0100 + + [atomics.ref.int, atomics.ref.float] Minor \tcode fixes (#7499) + + commit daae8f9a9b959c099e99f248324af95bbaf11779 + Author: A. Jiang + Date: Wed Dec 18 03:09:10 2024 +0800 + + [flat.{map,multimap,set,multiset}] Exposition-only formatting (#6404) + + commit 7cbd07c13063b9730d51385198e13bb036d40377 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 16 11:08:10 2024 +0100 + + [depr.meta.types] Remove superfluous period + + commit 7fe908fa11ad69138975bfec2cf376c66a536d08 + Author: Alisdair Meredith + Date: Tue Dec 17 14:13:02 2024 -0500 + + [cpp] Distinguish "preprocessing token" from "token" (#7482) + + commit 9c9d19f6aef145cf2c074dcdd343e7a2446417a9 + Author: Jonathan Wakely + Date: Fri Dec 6 17:37:05 2024 +0000 + + [sequence.reqmts] Remove unnecessary qualification of which new element + + There is only one new element, and this avoids having to decide whether it should say args.... diff --git a/papers/n5009.html b/papers/n5009.html new file mode 100644 index 0000000000..ec21ca1bed --- /dev/null +++ b/papers/n5009.html @@ -0,0 +1,893 @@ + + + + + +N5009 + + +

N5009 Editors’ Report:
Programming Languages — C++

+ +

Date: 2025-03-15

+ +

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, +to those who have provided pull requests with fixes, +and to everyone who drafted motion applications.

+ +

New papers

+ +
    +
  • N5008 is the +current working draft for C++26. It replaces +N5001.
  • +
  • N5009 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

LWG Poll 2 was retracted.

+ +

Library issue LWG4189, +adopted by LWG Poll 1 (P3615R0) had the effect of making most of the content of <ranges> +free-standing by default, with the note that "[m]ost future additions to this header should +have no problem being freestanding, so that is the right default." Absent an explicit +opt-out, the new facilities from LWG Poll 14 +(P2846R6), +reserve_hint and approximately_sized_range, are now free-standing as well.

+ +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +P3638R0 +(Core Language Working Group "ready" Issues for the February, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the changes in P3542R0 +(Abolish the term "converting constructor") to the C++ Working Paper.

+ +

CWG Poll 3. Apply the changes in P3074R7 +(trivial unions (was std::uninitialized)) to the C++ Working Paper.

+ +

CWG Poll 4. Apply the changes in P1494R5 +(Partial program correctness) to the C++ Working Paper.

+ +

CWG Poll 5. Apply the changes in P2900R14 +(Contracts for C++) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in P3475R2 +(Defang and deprecate memory_order::consume) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in P2841R7 +(Concept and variable-template template-parameters) to the C++ Working Paper.

+ +

CWG Poll 8. Apply the changes in P2786R13 +(Trivial Relocatability For C++26) to the C++ Working Paper.

+ +

CWG Poll 9. Apply the changes in P1967R14 +(#embed - a simple, scannable preprocessor-based resource acquisition method) to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes for all Tentatively Ready issues in +P3615R0 +(C++ Standard Library Ready Issues to be moved in Hagenberg, Feb. 2025) to the C++ working paper.

+ +

LWG Poll 2 was retracted.

+ +

LWG Poll 3. Apply the changes in P3137R3 +(views::to_input) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in P0472R3 +(Put std::monostate in <utility>) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in P3349R1 +(Converting contiguous iterators to pointers) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in P3372R3 +(constexpr containers and adaptors) to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in P3378R2 +(constexpr exception types) to the C++ working paper.

+ +

LWG Poll 8. Apply the changes in P3441R2 +(Rename simd_split to simd_chunk) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in P3287R3 +(Exploration of namespaces for std::simd) to the C++ working paper.

+ +

LWG Poll 10. Apply the changes in P2976R1 +(Freestanding Library: algorithm, numeric, and random) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in P3430R3 +(SIMD issues: explicit, unsequenced, identity-element position, and members of disabled SIMD) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in P2663R7 +(Interleaved complex values support in std::simd) to the C++ working paper.

+ +

LWG Poll 13. Apply the changes in P2933R4 +(Extend <bit> header function with overloads for std::simd) to the C++ working paper.

+ +

LWG Poll 14. Apply the changes in P2846R6 +(reserve_hint: Eagerly reserving memory for not-quite-sized lazy ranges) to the C++ working paper.

+ +

LWG Poll 15. Apply the changes in P3471R4 +(Standard Library Hardening) to the C++ working paper.

+ +

LWG Poll 16. Apply the changes in P0447R28 +(Introduction of std::hive to the standard library) to the C++ working paper.

+ +

LWG Poll 17. Apply the changes in P3019R14 +(indirect and polymorphic: Vocabulary Types for Composite Class Design) to the C++ working paper.

+ +

Editorial changes

+ +

Major editorial changes

+ +

There have not been any major editorial changes.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N5001 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 f3676cb1550f1501236cc65c1dfa2dec957bbdf2
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Tue Dec 17 14:15:10 2024 -0700
+
+    [linalg.conj.conjugated] Remove inappropriate "expression-equivalent" wording (#7497)
+
+    This phrase appears to be copy-pasted from elsewhere, but is not meaningful here.
+
+commit be0a25c9a2f2c1f498b0ff84a33c28adae41863e
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Dec 17 20:31:14 2024 +0100
+
+    [simd.alg] Fix range syntax
+
+commit a18040f05ff6a27e5c6425005ab1b21515ad952c
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Nov 1 08:06:28 2024 +0100
+
+    [basic.compound] Update introduction
+
+commit 0131e015c09eca1901d0bfa46744a6c7ab31b00d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Dec 17 21:21:42 2024 +0000
+
+    [linalg.helpers] Rename template parameter for poison pills
+
+    This avoids reusing `T` which is also used for the type of the
+    subexpression E.
+
+    Fixes #7494
+
+commit 04169bac7059322ad8bf32e605a80e57ef30b922
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 17 22:51:01 2024 +0100
+
+    [inplace.vector.overview] Replace residual use of 'trivial type'
+
+commit 9272753d0ecbc1df9d08178793795f06b623a451
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Nov 19 16:41:00 2024 +0800
+
+    [flat.map.defn, flat.set.defn] Avoid naming the from_range_t tag
+
+commit 85de0af0e0af416f7e73ac096254641c31bf11cc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 17 23:19:21 2024 +0100
+
+    [basic.fundamental] Ensure consistency with [conv.ptr]
+
+commit 561a4d8cde9e434fe206b88489e95b0e5271f469
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Thu Dec 19 14:35:50 2024 -0700
+
+    [bibliography] Fix spelling and formatting (#7507)
+
+    Fix spelling of one author's name.  Add missing commas
+    and extra spaces after a period ending authors' abbreviated
+    first or middle names.
+
+commit 82153790d8904ea82bc57edc8885b02925e85e93
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Thu Dec 19 14:41:02 2024 -0700
+
+    [simd.general, bibliography] Add SIMD acronym explanation and bibliographic reference (#7504)
+
+    To the existing Note at the beginning of [simd.general],
+    add text that unpacks the SIMD acronym and refers to Flynn 1966.
+
+    Add bibliography entry for Flynn 1966, the paper that introduced what
+    later became known as "Flynn's Taxonomy."  This classifies parallel
+    computer hardware as SISD, SIMD, MISD, or MIMD.
+
+commit e1a368bc157f824cee7702e87a2cca1951e60f98
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Dec 19 11:02:38 2024 +0000
+
+    [mdspan.sub] Change to "unit-stride slice for mapping"
+
+    This was the wording requested by LWG and approved in P3355R2, but I
+    mistakenly put P3355R1 in the straw polls.
+
+commit 2d3ac367d8605d7172151726e873daea295a573a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Dec 20 10:15:46 2024 +0100
+
+    [diff.cpp03.library] Correct \effect to \change
+
+    - Correct \effect to \change.
+    - Add period at end.
+    - Add \tcode for swap.
+
+commit a2429a5944b71e3563dc09730426af43fb4b53e1
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 26 01:37:34 2024 +0000
+
+    [class.expl.init] Fix incorrect note
+
+commit 1411cf56fcb41f9fd000406185f17ef47235d26a
+Author: Bronek Kozicki <brok@incorrekt.com>
+Date:   Wed Jan 1 17:00:14 2025 +0000
+
+    [expected.bad.void] Fix syntax error in bad_expected_access<void> (#7529)
+
+    Introduced by commit 8c997445c176c81a334e77f9344b91abc72b2772
+
+commit a137940ac9c807e3ea809c3ff0b3a863795bf742
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 1 22:18:37 2025 +0100
+
+    [filebuf.members,fs.path.req] Fix indefinite article (#7530)
+
+commit d2b48043fcc219b2a141af39dae2eb85934c0847
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 2 10:49:14 2025 +0100
+
+    [expr.const] Properly merge P2686R5
+
+    P2686R5 (applied by commit e220906b71df01f09fe60921e8fac39b80558f78)
+    accidentally reverted a change considering erroneous values made by
+    P2795R5.
+
+commit 22937c04da139226c186973eda2cdb79df640b5b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jan 2 15:14:06 2025 +0100
+
+    [format.arg] Fix indefinite article (#7536)
+
+commit 75af9f7f8cd816e1908eb2a3917eb7749c11471a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Jan 4 02:18:53 2025 +0700
+
+    [tuple.helper] Remove redundant 'public' in base-specifier of struct (#7539)
+
+commit 6ff55d533f72b7222e022513dcb80982f4e887a0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 30 16:34:49 2024 +0100
+
+    [lex.icon,depr.locale.category] Remove duplicate 'table' in front of table references
+
+commit 70df8aa8f4a30a7d54a604cbe01ebe13f5973043
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 8 13:51:13 2025 +0100
+
+    [linalg.algs.blas2.gemv] Fix singular/plural mismatch (#7546)
+
+commit 0164098f821ae002469c6f23cd03fc66a0a2f7ca
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Jan 9 10:01:36 2025 +0000
+
+    [basic.def.odr] Fix typo and reference the correct subclause
+
+commit 2734ddeb05115f3fddf09c9c15b843083575e9df
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jan 10 13:13:28 2025 +0100
+
+    [exec.async.ops] Remove stray closing parenthesis (#7555)
+
+commit 77171de904e6008f31717615d5baabf604baeea8
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Jan 10 23:05:58 2025 +0800
+
+    [locale.time.put.members] Remove incorrect footnote (#7553)
+
+commit 6ecd1be67c71001db37883ee45b76cc66ef4101f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 13 22:34:47 2025 +0100
+
+    [exec.getcomplsigs] Add missing LaTeX escaping of braces (#7541)
+
+commit 1b1914ed868b0b29e63d0d1e4b872daf07b50740
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jan 14 14:31:09 2025 +0100
+
+    [simd.traits] Remove stray closing parenthesis (#7563)
+
+commit 0ac6f9d7e94a70b48457f289bcbeb069a4662c28
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 15 14:10:57 2025 +0100
+
+    [locale.moneypunct.general] Insert period at end (#7564)
+
+commit 96fad4cf7ff48c8a4ae5442580d55008fb56ca43
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 15 10:06:49 2025 -0500
+
+    [inplace.vector.overview] Remove spurious semicolon closing namespace std (#7566)
+
+commit 1c398ffc71845163ca50b712f1edd9e1b2a87772
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 17 17:11:02 2025 +0000
+
+    [type.info] Remove comments explaining deleted members
+
+    The standard is not a tutorial.
+
+commit 569e2a38cf1aa6d185b4c4d1817d9496ebd087e5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 18 09:18:53 2025 +0100
+
+    [exec.snd.expos] Move write-env paragraph into itemdescr (#7571)
+
+commit 93aa7cb89b375280cb2d5f385fb0c5a5874e9243
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jan 18 23:32:20 2025 +0100
+
+    [re.err,re.alg.match,re.tokiter.incr] Add period at end for consistency (#7574)
+
+commit ce5fd62b98d822228f46319f4516e34c492fa257
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 22 16:15:57 2025 +0100
+
+    [string.view.io,string.insert] Add period at end of "Returns" (#7579)
+
+commit 5c4823a05b83a67f7550fdcc1476f8000c29514c
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jan 23 11:31:05 2025 +0800
+
+    [expr.const] Re-apply CWG2909
+
+commit db563eecdfb63cb24f10afb30f001a0bc6213997
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 15 07:59:51 2025 -0500
+
+    [lex.phases] Update implementation defined text
+
+    Since C++23 we no longer have physical source files, but rather
+    input files.  Update the two implementation-defined references
+    to the mapping from input file to translation character set
+    using the same phrasing so that they provide the same entry
+    in the index of implementation-defined behavior, just as they
+    did in C++20, before getting out of sync when the terminology
+    changed.
+
+commit a39cca2e9c009766da1e205daf5d7bf8cbdccaa3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jan 23 07:28:40 2025 -0500
+
+    [linalg.conj.conjugated] Rearrange to match P3050R3 (#7506)
+
+    This was the wording requested by LWG and approved in P3050R3, but I
+    mistakenly put P3050R2 in the straw polls.
+
+commit 6583c4ac9c2d3bbfb7daac0c79c902a30417c50f
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Sat Jan 25 14:11:30 2025 +0100
+
+    [std] Use template-parameter and template parameter more consistently (#7460)
+
+    Try to use template-parameter only when we refer to a
+    grammar construct, and to 'template parameter' everywhere else.
+
+    Adopt the same logic to template-argument/template argument.
+
+    This change might not be  exhaustive.
+
+    The aim is to editorially adopt some of the wording changes
+    made in P2841R5 to ease its review in core.
+
+commit 696dcd809ceed3fc10502161963f8ce13505ec1a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 25 21:25:32 2025 +0100
+
+    [format.string.general,format.formatter.spec] Fix unparenthesized cross-references
+
+commit 47cf5a67357543b0d45d0072f42fdd29fa028cca
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 29 09:29:54 2025 +0100
+
+    [alg.rand.generate] Add period at end of "Returns" (#7595)
+
+commit b2b266e7b67eb583c50c34a9eceffe44f72ea2f6
+Author: Ivan Lazarić <ivan.lazaric1@gmail.com>
+Date:   Sat Feb 1 09:56:42 2025 +0100
+
+    [temp.res.general] Fix nesting for \terminal{\opt{...}} (#7599)
+
+commit d51e6bedd991d55b7f7fb7f41e1f08083cfd1b1d
+Author: Eric Niebler <eniebler@boost.org>
+Date:   Mon Feb 3 12:05:48 2025 -0800
+
+    [range.view] Change incorrect uses of "which" to "that" (#7606)
+
+commit 1d49b05d1b48a2daa2a88d854e2367e6648c3cb6
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Feb 3 21:14:45 2025 +0100
+
+    [tuple.assign] Remove incorrect comma at end (#7609)
+
+commit 2e1b856b6187fe9a5c74782948982eefd128ecbf
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Feb 3 16:17:48 2025 -0500
+
+    [diff.cpp.library] Add new C23 headers to list of new headers
+
+commit cae9b2a645d5bb91caffc061325f107605e85a0d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Feb 4 09:30:49 2025 +0100
+
+    [container.alloc.reqmts,sequence.reqmts] Add period at end (#7614)
+
+commit 003506a2779c519d4929cce75c7adeb1b7a76955
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 1 18:45:19 2025 +0700
+
+    [macros] Add LaTeX macros to index library macros
+
+    The immediate idea is to support using the new macros directly
+    in header synopses when defining each library macro.  This will
+    ensure that no macros are accidentally not indexed.
+
+    A follow-up plan is that this separation of library macros will
+    make it easier to create a separate index of macros, or apply
+    other macro-specific renderings, in the future.  To this end,
+    all indexed uses of a macro, not just those in header files,
+    should be replaced by use of these new macros.  Similarly,
+    these LaTeX macros can be used in-place in regular text to
+    index cross-references where standard library macros are used
+    throughout the standard.
+
+commit d7618b4d20a24b37677b92c2fbd80dcee4565bc3
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Feb 7 09:37:37 2025 +0100
+
+    [diff.lex] Add period at end (#7618)
+
+commit 040ff41df1d0e0e4d31bd6c76f084fbc84239e7f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Feb 8 07:56:45 2025 +0000
+
+    [fs.op.current.path] Remove note discussing design choices (#7620)
+
+commit dfdc64cbdc842f0f7d2a060440ea907b41ce78e6
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Sun Feb 9 20:12:44 2025 +0400
+
+    [basic.scope.scope] Update the note about special cases (#7594)
+
+commit 8948fd9bd8f799d50fc9cbff34b349b9d59157f1
+Author: André Brand <andre.brand@mailbox.org>
+Date:   Sun Feb 9 17:18:12 2025 +0100
+
+    [temp.mem.enum] Remove instantiation in example [temp.inst] (#7558)
+
+    The example is inconsistent with [temp.inst]p3. Since the implicit instantiation
+    does not contribute to the point of [temp.mem.enum], the inconsistency
+    can be resolved by omitting the instantiation.
+
+commit 0d0ea5582082f85fa707c680634044209c2e343d
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Nov 18 13:47:37 2024 +0000
+
+    [defns.argument] Mention braced-init-list
+
+commit 7566675c778f95ef966c4fea058a895def98e6d1
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Feb 9 11:23:22 2025 -0500
+
+    [lex.phases] Use preprocessing token consistently (#7361)
+
+    Prior to converting preprocessing tokens to tokens in phase 7,
+    all tokens are strictly preprocessing tokens.
+
+commit b9f054b0cba3a36f9c8eff0c190f85996597dc3d
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Mon Feb 10 07:47:58 2025 +0100
+
+    [std] Rename "non-type" to "constant" template parameter/argument (#7587)
+
+    Note that not all instances of "non-type" have been mechanically replaced,
+    as [dcl] and [diff] use the term to refer to anything that is not a type
+    in the context of lookup.
+
+commit 45eb50507a1b6477dea6106c3c26654b96feae4a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Jan 31 14:04:53 2025 -0500
+
+    [cmath.syn] Consolidate std namespaces
+
+    There is no ordering dependency between the two typedefs
+    in namespace std, the macros that follow, and teh next
+    opening of namespace std, so move the two typedefs to
+    avoid repeatedly opening an closing the namespace.
+
+    Note that we could have done this without moving
+    the typedefs as macros are not bound by namespaces,
+    but our convention very sensibly avoids confusing
+    readers by keeping macro definitions outside of
+    namespaces.
+
+commit 5eab5c6b456db2424b04becb791b23dbf4de356a
+Author: Axel Naumann <Axel.Naumann@cern.ch>
+Date:   Mon Jan 27 15:50:24 2025 +0100
+
+    [class.prop] add ref to actual layout spec in [expr.rel]
+
+commit 2f42a31044cc1ec8cf119b0fd595fdcc1d625c59
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jan 23 11:37:15 2025 +0800
+
+    [util.smartptr.atomic.{shared,weak}] Fix wording for initialization
+
+    By using more conventional "value-initializes".
+
+commit 4e026ec784007b492eb3d904663cfdc4bf905fd3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 4 11:09:05 2025 +0000
+
+    [fs.op.funcs] Remove empty parens when referring to functions by name
+
+    As per the Specification Style Guidelines.
+
+    https://github.com/cplusplus/draft/wiki/Specification-Style-Guidelines#describing-function-calls
+
+commit 7f00883b8f65307b7e0df0ad2e55182d699d2804
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 13 22:33:34 2025 +0100
+
+    [xrefdelta] Restore cross-references since C++17
+
+commit 7fbdb79d99338d9aa91f382760ff6e1cb0353c71
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 1 09:20:10 2024 -0400
+
+    [except.uncaught] Tidy the specification for uncaught exceptions
+
+    Several concurrent fixes.  First include the normative wording
+    that 'uncaught_exceptions' returns the number of uncaught
+    exceptions *on the current thread*.  This wording is present
+    in the core language.
+
+    Then move the core wording for when an exception is uncaught
+    directly into the text that talks about caught and uncaught
+    exceptions.  In the process, turn the reference to into a note,
+    so that there is only one normative specification.
+
+    Finally, remove [except.uncaught] as it is now empty.
+
+commit 70abf300ddbb1074cd16e9a5febe7f7c88bdff3d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 20 02:07:51 2024 +0100
+
+    [except.special.general] Complete the set of clause 17 references
+
+commit 888b0510da303e367f7421ac34607a158ddfc453
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jan 21 04:31:34 2025 -0500
+
+    [basic.pre] Defragment specification of names and entities
+
+    The current contents of [basic.pre] jump between specifying
+    different things.  This PR moves all the specification of
+    names to the front, followed by the specification of entities.
+
+    There are two main benefits: (1) the specification for when
+    two names are the same is a list of 4 rules that correspond
+    to the 4 things than can form a name --- the connection is
+    much clearer when the paragraphs are adjacent and the list
+    is sorted to the same order; (2) in this form, even though
+    all the words are the same, the reordering and merging of
+    paragraphs a fit on a single page.  The very last paragraph
+    was forced over a page-break in the original layout.
+
+commit 5be40a6b59527e82b13a29722c623635065759bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Feb 11 21:42:20 2025 +0100
+
+    [expr.lval] Update cross reference for "invalid pointer value"
+
+commit 83530f54892686c9ba055434d02dfadc00bbb290
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 00:54:57 2023 +0800
+
+    [basic.extended.fp] Use "declared" for typedef-names
+
+commit 1542d983b3f690876720d69a44dff2c5574617b3
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 01:00:16 2023 +0800
+
+    [expr.{add,alignof,sizeof}] Use "typedef-name", avoid "defined"
+
+commit 152693b46648ea99493aecedbc8051aa2ab7542f
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Feb 12 17:58:51 2025 +0000
+
+    [temp.param, temp.constr.normal] Use \dotsc for a non-code ellipsis (#7397)
+
+commit 930b8f97b0ab7bd9442bd0faf10f7302da5fc89a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Feb 12 19:22:47 2025 +0100
+
+    [diff.cpp03.library] Fix cross-reference to restriction on macro names
+
+commit 2cfc175a01d2bff1daf084d5c776017c5c049872
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Feb 13 22:28:24 2025 +0000
+
+    [linalg.general] Remove extraneous dot (#7637)
+
+commit 422ded52d1876578f4eeb3bc30d583a193b94f42
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Feb 14 19:13:02 2025 +0100
+
+    [conv.rank] Fix typo
+
+commit 10468bf63eee8926b84b76a10abb2a7d05b43c02
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Feb 16 12:13:43 2025 +0100
+
+    [map.overview] Fix punctuation (#7677)
+
+commit a103bf3ea67a731189a8f1453d3e9ab88d589eba
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Feb 24 07:46:22 2025 -0500
+
+    [xrefdelta] Consolidate restored entries (#7631)
+
+    Several entries in the restored larger delta referred
+    to stable labels that have since moved again, or have been
+    removed.  This commit updates their cross-references
+    accordingly, or marks them as removed if appropriate.
+
+commit 9854e729ba5ade9a41bf047b6a5fe6f4bbe038e0
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Thu Feb 13 17:01:13 2025 -0500
+
+    [basic.types.general] Change ordering to "non-variant non-static"
+
+    The definition of literal type is the only place where "non-static
+    non-variant data member" is used as opposed to "non-variant non-static
+    data member".
+
+    Change to use the canonical ordering.
+
+commit c31b8f4111dfa9dd598220b9c6f8c1cf9d4a9b34
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 25 09:54:40 2025 +0000
+
+    [support.srcloc.cons] Update xref to [class.mem.general]
+
+    The cross-reference to [class.mem] was referring to a hanging paragraph
+    that was fixed by 2850139be6285ba10a64fb718125a80ca967c631 so we should
+    be referring to [class.mem.general] now.
+
+commit 912e5cab7565be0daa9c0c6d7c178600b3cd38e6
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sat Mar 15 20:23:43 2025 +0000
+
+    [functional.{syn,bind.place}] Use \vdots; add missing \placeholder (#7723)
+
+commit 0dda8468be890adf880afddc37e449cbc40607cb
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Mar 16 04:26:10 2025 +0800
+
+    [expr.const] Change "value" to "result object" (of a prvalue) (#6267)
+
+commit 4552a92a01a2d1b032264cd6568a860a5244918b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 7 22:35:21 2021 +0100
+
+    [lex.string] Clarify size of string-literal
+
+commit ec10aaec4e6daac66b7b28426abcc765494194c9
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Sat Mar 15 16:41:54 2025 -0400
+
+    [debugging.utility] Clarify wording in notes
+
+    The previous wording in the notes in `breakpoint` and `is_debugger_present`
+    read as statements of fact about the implementation-defined behaviour.
+    The statements are actually ones of intent.
+
+    The specific claim in `breakpoint` that the debugger resumes execution of the program
+    as if the function was not invoked is confusing considering that the debugger may effect
+    side-effects or cause execution to resume from a different evaluation.
+
+    Instead, the idea is that `breakpoint` is not responsible for causing the translation process
+    to make special accomodations for resumption of execution other than in cases
+    where the debugger was strictly used for observation only.
+
+    In `is_debugger_present`, the functionality ascribed to POSIX by the wording
+    ("ptrace") is not present in POSIX. Update to reference the LSB and to use
+    the corresponding terminology ("tracing process").
+
+    The wording implies a preference to return `true` in case it is unknown
+    whether a debugger is present. Add a critical "only" to fix that.
+
+commit 598910dc970bc0bc840ba797983e9bc131cd826e
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Feb 25 07:51:44 2025 +0800
+
+    [ifstream.members] Remove mistakenly added `@`
+
+commit 4b5a0080230ed74d796a3ee909bdde66e2f2b395
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Aug 7 18:45:41 2024 +0800
+
+    [func.wrap.func] Drop Lvalue-Callable
+
+    Replace its usages with `is_invocable_r_v` and remove an unnecessary index.
+
+commit f9847af90413adb0436aae9f6895b4a2e0e173ec
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Feb 17 11:44:11 2025 +0800
+
+    [containers, strings, algorithms, re] Use \range where appropriate
+
+    Currently, there are several cases where `\tcode{[i, j)}` is used for
+    specifying left-closed right-open intervals, where `\range{i}{j}` is proper.
+
+    Co-authored-by: Eelis van der Weegen <eelis@eelis.net>
+
+commit 73699cf37d247a7c1f3a6879197c730a14666b90
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Feb 26 02:55:52 2021 +0300
+
+    [class.cdtor] Only objects of scalar type can be accessed
+
+ + diff --git a/papers/n5009.md b/papers/n5009.md new file mode 100644 index 0000000000..2caf3f0571 --- /dev/null +++ b/papers/n5009.md @@ -0,0 +1,753 @@ +# N5009 Editors' Report -- Programming Languages -- C++ + +Date: 2025-03-15 + +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), +to those who have provided pull requests with fixes, +and to everyone who drafted motion applications. + +## New papers + + * [N5008](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf) is the + current working draft for C++26. It replaces + [N5001](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n5001.pdf). + * N5009 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +LWG Poll 2 was retracted. + +Library issue [LWG4189](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3615r0.html#4189), +adopted by LWG Poll 1 (P3615R0) had the effect of making most of the content of `` +free-standing by default, with the note that "[m]ost future additions to this header should +have no problem being freestanding, so that is the right default." Absent an explicit +opt-out, the new facilities from LWG Poll 14 +([P2846R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2846r6.html)), +`reserve_hint` and `approximately_sized_range`, are now free-standing as well. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +[P3638R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3638r0.html) +(Core Language Working Group "ready" Issues for the February, 2025 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the changes in [P3542R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3542r0.html) +(Abolish the term "converting constructor") to the C++ Working Paper. + +CWG Poll 3. Apply the changes in [P3074R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3074r7.html) +(trivial unions (was `std::uninitialized`)) to the C++ Working Paper. + +CWG Poll 4. Apply the changes in [P1494R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1494r5.html) +(Partial program correctness) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in [P2900R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2900r14.pdf) +(Contracts for C++) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in [P3475R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3475r2.pdf) +(Defang and deprecate `memory_order::consume`) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in [P2841R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2841r7.pdf) +(Concept and variable-template template-parameters) to the C++ Working Paper. + +CWG Poll 8. Apply the changes in [P2786R13](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2786r13.html) +(Trivial Relocatability For C++26) to the C++ Working Paper. + +CWG Poll 9. Apply the changes in [P1967R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1967r14.html) +(`#embed` - a simple, scannable preprocessor-based resource acquisition method) to the C++ Working Paper. + +### Library working group polls + +LWG Poll 1. Apply the changes for all Tentatively Ready issues in +[P3615R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3615r0.html) +(C++ Standard Library Ready Issues to be moved in Hagenberg, Feb. 2025) to the C++ working paper. + +LWG Poll 2 was retracted. + +LWG Poll 3. Apply the changes in [P3137R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3137r3.html) +(`views::to_input`) to the C++ working paper. + +LWG Poll 4. Apply the changes in [P0472R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0472r3.pdf) +(Put `std::monostate` in ``) to the C++ working paper. + +LWG Poll 5. Apply the changes in [P3349R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3349r1.html) +(Converting contiguous iterators to pointers) to the C++ working paper. + +LWG Poll 6. Apply the changes in [P3372R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) +(constexpr containers and adaptors) to the C++ working paper. + +LWG Poll 7. Apply the changes in [P3378R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3378r2.html) +(constexpr exception types) to the C++ working paper. + +LWG Poll 8. Apply the changes in [P3441R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3441r2.html) +(Rename `simd_split` to `simd_chunk`) to the C++ working paper. + +LWG Poll 9. Apply the changes in [P3287R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3287r3.pdf) +(Exploration of namespaces for `std::simd`) to the C++ working paper. + +LWG Poll 10. Apply the changes in [P2976R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2976r1.html) +(Freestanding Library: algorithm, numeric, and random) to the C++ working paper. + +LWG Poll 11. Apply the changes in [P3430R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3430r3.pdf) +(SIMD issues: explicit, unsequenced, identity-element position, and members of disabled SIMD) to the C++ working paper. + +LWG Poll 12. Apply the changes in [P2663R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2663r7.html) +(Interleaved complex values support in `std::simd`) to the C++ working paper. + +LWG Poll 13. Apply the changes in [P2933R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2933r4.html) +(Extend `` header function with overloads for `std::simd`) to the C++ working paper. + +LWG Poll 14. Apply the changes in [P2846R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2846r6.pdf) +(`reserve_hint`: Eagerly reserving memory for not-quite-sized lazy ranges) to the C++ working paper. + +LWG Poll 15. Apply the changes in [P3471R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3471r4.html) +(Standard Library Hardening) to the C++ working paper. + +LWG Poll 16. Apply the changes in [P0447R28](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0447r28.html) +(Introduction of `std::hive` to the standard library) to the C++ working paper. + +LWG Poll 17. Apply the changes in [P3019R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf) +(`indirect` and `polymorphic`: Vocabulary Types for Composite Class Design) to the C++ working paper. + +## Editorial changes + +### Major editorial changes + +There have not been any major editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N5001 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/n5001...n5008). + + commit f3676cb1550f1501236cc65c1dfa2dec957bbdf2 + Author: Mark Hoemmen + Date: Tue Dec 17 14:15:10 2024 -0700 + + [linalg.conj.conjugated] Remove inappropriate "expression-equivalent" wording (#7497) + + This phrase appears to be copy-pasted from elsewhere, but is not meaningful here. + + commit be0a25c9a2f2c1f498b0ff84a33c28adae41863e + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Dec 17 20:31:14 2024 +0100 + + [simd.alg] Fix range syntax + + commit a18040f05ff6a27e5c6425005ab1b21515ad952c + Author: Eisenwave + Date: Fri Nov 1 08:06:28 2024 +0100 + + [basic.compound] Update introduction + + commit 0131e015c09eca1901d0bfa46744a6c7ab31b00d + Author: Jonathan Wakely + Date: Tue Dec 17 21:21:42 2024 +0000 + + [linalg.helpers] Rename template parameter for poison pills + + This avoids reusing `T` which is also used for the type of the + subexpression E. + + Fixes #7494 + + commit 04169bac7059322ad8bf32e605a80e57ef30b922 + Author: Jens Maurer + Date: Tue Dec 17 22:51:01 2024 +0100 + + [inplace.vector.overview] Replace residual use of 'trivial type' + + commit 9272753d0ecbc1df9d08178793795f06b623a451 + Author: Hewill Kang + Date: Tue Nov 19 16:41:00 2024 +0800 + + [flat.map.defn, flat.set.defn] Avoid naming the from_range_t tag + + commit 85de0af0e0af416f7e73ac096254641c31bf11cc + Author: Jens Maurer + Date: Tue Dec 17 23:19:21 2024 +0100 + + [basic.fundamental] Ensure consistency with [conv.ptr] + + commit 561a4d8cde9e434fe206b88489e95b0e5271f469 + Author: Mark Hoemmen + Date: Thu Dec 19 14:35:50 2024 -0700 + + [bibliography] Fix spelling and formatting (#7507) + + Fix spelling of one author's name. Add missing commas + and extra spaces after a period ending authors' abbreviated + first or middle names. + + commit 82153790d8904ea82bc57edc8885b02925e85e93 + Author: Mark Hoemmen + Date: Thu Dec 19 14:41:02 2024 -0700 + + [simd.general, bibliography] Add SIMD acronym explanation and bibliographic reference (#7504) + + To the existing Note at the beginning of [simd.general], + add text that unpacks the SIMD acronym and refers to Flynn 1966. + + Add bibliography entry for Flynn 1966, the paper that introduced what + later became known as "Flynn's Taxonomy." This classifies parallel + computer hardware as SISD, SIMD, MISD, or MIMD. + + commit e1a368bc157f824cee7702e87a2cca1951e60f98 + Author: Jonathan Wakely + Date: Thu Dec 19 11:02:38 2024 +0000 + + [mdspan.sub] Change to "unit-stride slice for mapping" + + This was the wording requested by LWG and approved in P3355R2, but I + mistakenly put P3355R1 in the straw polls. + + commit 2d3ac367d8605d7172151726e873daea295a573a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Dec 20 10:15:46 2024 +0100 + + [diff.cpp03.library] Correct \effect to \change + + - Correct \effect to \change. + - Add period at end. + - Add \tcode for swap. + + commit a2429a5944b71e3563dc09730426af43fb4b53e1 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 26 01:37:34 2024 +0000 + + [class.expl.init] Fix incorrect note + + commit 1411cf56fcb41f9fd000406185f17ef47235d26a + Author: Bronek Kozicki + Date: Wed Jan 1 17:00:14 2025 +0000 + + [expected.bad.void] Fix syntax error in bad_expected_access (#7529) + + Introduced by commit 8c997445c176c81a334e77f9344b91abc72b2772 + + commit a137940ac9c807e3ea809c3ff0b3a863795bf742 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 1 22:18:37 2025 +0100 + + [filebuf.members,fs.path.req] Fix indefinite article (#7530) + + commit d2b48043fcc219b2a141af39dae2eb85934c0847 + Author: Jens Maurer + Date: Thu Jan 2 10:49:14 2025 +0100 + + [expr.const] Properly merge P2686R5 + + P2686R5 (applied by commit e220906b71df01f09fe60921e8fac39b80558f78) + accidentally reverted a change considering erroneous values made by + P2795R5. + + commit 22937c04da139226c186973eda2cdb79df640b5b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jan 2 15:14:06 2025 +0100 + + [format.arg] Fix indefinite article (#7536) + + commit 75af9f7f8cd816e1908eb2a3917eb7749c11471a + Author: Alisdair Meredith + Date: Sat Jan 4 02:18:53 2025 +0700 + + [tuple.helper] Remove redundant 'public' in base-specifier of struct (#7539) + + commit 6ff55d533f72b7222e022513dcb80982f4e887a0 + Author: Jens Maurer + Date: Mon Dec 30 16:34:49 2024 +0100 + + [lex.icon,depr.locale.category] Remove duplicate 'table' in front of table references + + commit 70df8aa8f4a30a7d54a604cbe01ebe13f5973043 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 8 13:51:13 2025 +0100 + + [linalg.algs.blas2.gemv] Fix singular/plural mismatch (#7546) + + commit 0164098f821ae002469c6f23cd03fc66a0a2f7ca + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Jan 9 10:01:36 2025 +0000 + + [basic.def.odr] Fix typo and reference the correct subclause + + commit 2734ddeb05115f3fddf09c9c15b843083575e9df + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jan 10 13:13:28 2025 +0100 + + [exec.async.ops] Remove stray closing parenthesis (#7555) + + commit 77171de904e6008f31717615d5baabf604baeea8 + Author: S. B. Tam + Date: Fri Jan 10 23:05:58 2025 +0800 + + [locale.time.put.members] Remove incorrect footnote (#7553) + + commit 6ecd1be67c71001db37883ee45b76cc66ef4101f + Author: Jens Maurer + Date: Mon Jan 13 22:34:47 2025 +0100 + + [exec.getcomplsigs] Add missing LaTeX escaping of braces (#7541) + + commit 1b1914ed868b0b29e63d0d1e4b872daf07b50740 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jan 14 14:31:09 2025 +0100 + + [simd.traits] Remove stray closing parenthesis (#7563) + + commit 0ac6f9d7e94a70b48457f289bcbeb069a4662c28 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 15 14:10:57 2025 +0100 + + [locale.moneypunct.general] Insert period at end (#7564) + + commit 96fad4cf7ff48c8a4ae5442580d55008fb56ca43 + Author: Alisdair Meredith + Date: Wed Jan 15 10:06:49 2025 -0500 + + [inplace.vector.overview] Remove spurious semicolon closing namespace std (#7566) + + commit 1c398ffc71845163ca50b712f1edd9e1b2a87772 + Author: Jonathan Wakely + Date: Fri Jan 17 17:11:02 2025 +0000 + + [type.info] Remove comments explaining deleted members + + The standard is not a tutorial. + + commit 569e2a38cf1aa6d185b4c4d1817d9496ebd087e5 + Author: Jens Maurer + Date: Sat Jan 18 09:18:53 2025 +0100 + + [exec.snd.expos] Move write-env paragraph into itemdescr (#7571) + + commit 93aa7cb89b375280cb2d5f385fb0c5a5874e9243 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jan 18 23:32:20 2025 +0100 + + [re.err,re.alg.match,re.tokiter.incr] Add period at end for consistency (#7574) + + commit ce5fd62b98d822228f46319f4516e34c492fa257 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 22 16:15:57 2025 +0100 + + [string.view.io,string.insert] Add period at end of "Returns" (#7579) + + commit 5c4823a05b83a67f7550fdcc1476f8000c29514c + Author: A. Jiang + Date: Thu Jan 23 11:31:05 2025 +0800 + + [expr.const] Re-apply CWG2909 + + commit db563eecdfb63cb24f10afb30f001a0bc6213997 + Author: Alisdair Meredith + Date: Wed Jan 15 07:59:51 2025 -0500 + + [lex.phases] Update implementation defined text + + Since C++23 we no longer have physical source files, but rather + input files. Update the two implementation-defined references + to the mapping from input file to translation character set + using the same phrasing so that they provide the same entry + in the index of implementation-defined behavior, just as they + did in C++20, before getting out of sync when the terminology + changed. + + commit a39cca2e9c009766da1e205daf5d7bf8cbdccaa3 + Author: Jonathan Wakely + Date: Thu Jan 23 07:28:40 2025 -0500 + + [linalg.conj.conjugated] Rearrange to match P3050R3 (#7506) + + This was the wording requested by LWG and approved in P3050R3, but I + mistakenly put P3050R2 in the straw polls. + + commit 6583c4ac9c2d3bbfb7daac0c79c902a30417c50f + Author: cor3ntin + Date: Sat Jan 25 14:11:30 2025 +0100 + + [std] Use template-parameter and template parameter more consistently (#7460) + + Try to use template-parameter only when we refer to a + grammar construct, and to 'template parameter' everywhere else. + + Adopt the same logic to template-argument/template argument. + + This change might not be exhaustive. + + The aim is to editorially adopt some of the wording changes + made in P2841R5 to ease its review in core. + + commit 696dcd809ceed3fc10502161963f8ce13505ec1a + Author: Jens Maurer + Date: Sat Jan 25 21:25:32 2025 +0100 + + [format.string.general,format.formatter.spec] Fix unparenthesized cross-references + + commit 47cf5a67357543b0d45d0072f42fdd29fa028cca + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 29 09:29:54 2025 +0100 + + [alg.rand.generate] Add period at end of "Returns" (#7595) + + commit b2b266e7b67eb583c50c34a9eceffe44f72ea2f6 + Author: Ivan Lazarić + Date: Sat Feb 1 09:56:42 2025 +0100 + + [temp.res.general] Fix nesting for \terminal{\opt{...}} (#7599) + + commit d51e6bedd991d55b7f7fb7f41e1f08083cfd1b1d + Author: Eric Niebler + Date: Mon Feb 3 12:05:48 2025 -0800 + + [range.view] Change incorrect uses of "which" to "that" (#7606) + + commit 1d49b05d1b48a2daa2a88d854e2367e6648c3cb6 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Feb 3 21:14:45 2025 +0100 + + [tuple.assign] Remove incorrect comma at end (#7609) + + commit 2e1b856b6187fe9a5c74782948982eefd128ecbf + Author: Alisdair Meredith + Date: Mon Feb 3 16:17:48 2025 -0500 + + [diff.cpp.library] Add new C23 headers to list of new headers + + commit cae9b2a645d5bb91caffc061325f107605e85a0d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Feb 4 09:30:49 2025 +0100 + + [container.alloc.reqmts,sequence.reqmts] Add period at end (#7614) + + commit 003506a2779c519d4929cce75c7adeb1b7a76955 + Author: Alisdair Meredith + Date: Wed Jan 1 18:45:19 2025 +0700 + + [macros] Add LaTeX macros to index library macros + + The immediate idea is to support using the new macros directly + in header synopses when defining each library macro. This will + ensure that no macros are accidentally not indexed. + + A follow-up plan is that this separation of library macros will + make it easier to create a separate index of macros, or apply + other macro-specific renderings, in the future. To this end, + all indexed uses of a macro, not just those in header files, + should be replaced by use of these new macros. Similarly, + these LaTeX macros can be used in-place in regular text to + index cross-references where standard library macros are used + throughout the standard. + + commit d7618b4d20a24b37677b92c2fbd80dcee4565bc3 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Feb 7 09:37:37 2025 +0100 + + [diff.lex] Add period at end (#7618) + + commit 040ff41df1d0e0e4d31bd6c76f084fbc84239e7f + Author: Jonathan Wakely + Date: Sat Feb 8 07:56:45 2025 +0000 + + [fs.op.current.path] Remove note discussing design choices (#7620) + + commit dfdc64cbdc842f0f7d2a060440ea907b41ce78e6 + Author: Vlad Serebrennikov + Date: Sun Feb 9 20:12:44 2025 +0400 + + [basic.scope.scope] Update the note about special cases (#7594) + + commit 8948fd9bd8f799d50fc9cbff34b349b9d59157f1 + Author: André Brand + Date: Sun Feb 9 17:18:12 2025 +0100 + + [temp.mem.enum] Remove instantiation in example [temp.inst] (#7558) + + The example is inconsistent with [temp.inst]p3. Since the implicit instantiation + does not contribute to the point of [temp.mem.enum], the inconsistency + can be resolved by omitting the instantiation. + + commit 0d0ea5582082f85fa707c680634044209c2e343d + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Nov 18 13:47:37 2024 +0000 + + [defns.argument] Mention braced-init-list + + commit 7566675c778f95ef966c4fea058a895def98e6d1 + Author: Alisdair Meredith + Date: Sun Feb 9 11:23:22 2025 -0500 + + [lex.phases] Use preprocessing token consistently (#7361) + + Prior to converting preprocessing tokens to tokens in phase 7, + all tokens are strictly preprocessing tokens. + + commit b9f054b0cba3a36f9c8eff0c190f85996597dc3d + Author: cor3ntin + Date: Mon Feb 10 07:47:58 2025 +0100 + + [std] Rename "non-type" to "constant" template parameter/argument (#7587) + + Note that not all instances of "non-type" have been mechanically replaced, + as [dcl] and [diff] use the term to refer to anything that is not a type + in the context of lookup. + + commit 45eb50507a1b6477dea6106c3c26654b96feae4a + Author: Alisdair Meredith + Date: Fri Jan 31 14:04:53 2025 -0500 + + [cmath.syn] Consolidate std namespaces + + There is no ordering dependency between the two typedefs + in namespace std, the macros that follow, and teh next + opening of namespace std, so move the two typedefs to + avoid repeatedly opening an closing the namespace. + + Note that we could have done this without moving + the typedefs as macros are not bound by namespaces, + but our convention very sensibly avoids confusing + readers by keeping macro definitions outside of + namespaces. + + commit 5eab5c6b456db2424b04becb791b23dbf4de356a + Author: Axel Naumann + Date: Mon Jan 27 15:50:24 2025 +0100 + + [class.prop] add ref to actual layout spec in [expr.rel] + + commit 2f42a31044cc1ec8cf119b0fd595fdcc1d625c59 + Author: A. Jiang + Date: Thu Jan 23 11:37:15 2025 +0800 + + [util.smartptr.atomic.{shared,weak}] Fix wording for initialization + + By using more conventional "value-initializes". + + commit 4e026ec784007b492eb3d904663cfdc4bf905fd3 + Author: Jonathan Wakely + Date: Tue Feb 4 11:09:05 2025 +0000 + + [fs.op.funcs] Remove empty parens when referring to functions by name + + As per the Specification Style Guidelines. + + https://github.com/cplusplus/draft/wiki/Specification-Style-Guidelines#describing-function-calls + + commit 7f00883b8f65307b7e0df0ad2e55182d699d2804 + Author: Jens Maurer + Date: Mon Jan 13 22:33:34 2025 +0100 + + [xrefdelta] Restore cross-references since C++17 + + commit 7fbdb79d99338d9aa91f382760ff6e1cb0353c71 + Author: Alisdair Meredith + Date: Tue Oct 1 09:20:10 2024 -0400 + + [except.uncaught] Tidy the specification for uncaught exceptions + + Several concurrent fixes. First include the normative wording + that 'uncaught_exceptions' returns the number of uncaught + exceptions *on the current thread*. This wording is present + in the core language. + + Then move the core wording for when an exception is uncaught + directly into the text that talks about caught and uncaught + exceptions. In the process, turn the reference to into a note, + so that there is only one normative specification. + + Finally, remove [except.uncaught] as it is now empty. + + commit 70abf300ddbb1074cd16e9a5febe7f7c88bdff3d + Author: Alisdair Meredith + Date: Wed Nov 20 02:07:51 2024 +0100 + + [except.special.general] Complete the set of clause 17 references + + commit 888b0510da303e367f7421ac34607a158ddfc453 + Author: Alisdair Meredith + Date: Tue Jan 21 04:31:34 2025 -0500 + + [basic.pre] Defragment specification of names and entities + + The current contents of [basic.pre] jump between specifying + different things. This PR moves all the specification of + names to the front, followed by the specification of entities. + + There are two main benefits: (1) the specification for when + two names are the same is a list of 4 rules that correspond + to the 4 things than can form a name --- the connection is + much clearer when the paragraphs are adjacent and the list + is sorted to the same order; (2) in this form, even though + all the words are the same, the reordering and merging of + paragraphs a fit on a single page. The very last paragraph + was forced over a page-break in the original layout. + + commit 5be40a6b59527e82b13a29722c623635065759bf + Author: Thomas Köppe + Date: Tue Feb 11 21:42:20 2025 +0100 + + [expr.lval] Update cross reference for "invalid pointer value" + + commit 83530f54892686c9ba055434d02dfadc00bbb290 + Author: A. Jiang + Date: Thu Aug 3 00:54:57 2023 +0800 + + [basic.extended.fp] Use "declared" for typedef-names + + commit 1542d983b3f690876720d69a44dff2c5574617b3 + Author: A. Jiang + Date: Thu Aug 3 01:00:16 2023 +0800 + + [expr.{add,alignof,sizeof}] Use "typedef-name", avoid "defined" + + commit 152693b46648ea99493aecedbc8051aa2ab7542f + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Feb 12 17:58:51 2025 +0000 + + [temp.param, temp.constr.normal] Use \dotsc for a non-code ellipsis (#7397) + + commit 930b8f97b0ab7bd9442bd0faf10f7302da5fc89a + Author: Alisdair Meredith + Date: Wed Feb 12 19:22:47 2025 +0100 + + [diff.cpp03.library] Fix cross-reference to restriction on macro names + + commit 2cfc175a01d2bff1daf084d5c776017c5c049872 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Feb 13 22:28:24 2025 +0000 + + [linalg.general] Remove extraneous dot (#7637) + + commit 422ded52d1876578f4eeb3bc30d583a193b94f42 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Feb 14 19:13:02 2025 +0100 + + [conv.rank] Fix typo + + commit 10468bf63eee8926b84b76a10abb2a7d05b43c02 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Feb 16 12:13:43 2025 +0100 + + [map.overview] Fix punctuation (#7677) + + commit a103bf3ea67a731189a8f1453d3e9ab88d589eba + Author: Alisdair Meredith + Date: Mon Feb 24 07:46:22 2025 -0500 + + [xrefdelta] Consolidate restored entries (#7631) + + Several entries in the restored larger delta referred + to stable labels that have since moved again, or have been + removed. This commit updates their cross-references + accordingly, or marks them as removed if appropriate. + + commit 9854e729ba5ade9a41bf047b6a5fe6f4bbe038e0 + Author: Hubert Tong + Date: Thu Feb 13 17:01:13 2025 -0500 + + [basic.types.general] Change ordering to "non-variant non-static" + + The definition of literal type is the only place where "non-static + non-variant data member" is used as opposed to "non-variant non-static + data member". + + Change to use the canonical ordering. + + commit c31b8f4111dfa9dd598220b9c6f8c1cf9d4a9b34 + Author: Jonathan Wakely + Date: Tue Feb 25 09:54:40 2025 +0000 + + [support.srcloc.cons] Update xref to [class.mem.general] + + The cross-reference to [class.mem] was referring to a hanging paragraph + that was fixed by 2850139be6285ba10a64fb718125a80ca967c631 so we should + be referring to [class.mem.general] now. + + commit 912e5cab7565be0daa9c0c6d7c178600b3cd38e6 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sat Mar 15 20:23:43 2025 +0000 + + [functional.{syn,bind.place}] Use \vdots; add missing \placeholder (#7723) + + commit 0dda8468be890adf880afddc37e449cbc40607cb + Author: A. Jiang + Date: Sun Mar 16 04:26:10 2025 +0800 + + [expr.const] Change "value" to "result object" (of a prvalue) (#6267) + + commit 4552a92a01a2d1b032264cd6568a860a5244918b + Author: Jens Maurer + Date: Sun Nov 7 22:35:21 2021 +0100 + + [lex.string] Clarify size of string-literal + + commit ec10aaec4e6daac66b7b28426abcc765494194c9 + Author: Hubert Tong + Date: Sat Mar 15 16:41:54 2025 -0400 + + [debugging.utility] Clarify wording in notes + + The previous wording in the notes in `breakpoint` and `is_debugger_present` + read as statements of fact about the implementation-defined behaviour. + The statements are actually ones of intent. + + The specific claim in `breakpoint` that the debugger resumes execution of the program + as if the function was not invoked is confusing considering that the debugger may effect + side-effects or cause execution to resume from a different evaluation. + + Instead, the idea is that `breakpoint` is not responsible for causing the translation process + to make special accomodations for resumption of execution other than in cases + where the debugger was strictly used for observation only. + + In `is_debugger_present`, the functionality ascribed to POSIX by the wording + ("ptrace") is not present in POSIX. Update to reference the LSB and to use + the corresponding terminology ("tracing process"). + + The wording implies a preference to return `true` in case it is unknown + whether a debugger is present. Add a critical "only" to fix that. + + commit 598910dc970bc0bc840ba797983e9bc131cd826e + Author: A. Jiang + Date: Tue Feb 25 07:51:44 2025 +0800 + + [ifstream.members] Remove mistakenly added `@` + + commit 4b5a0080230ed74d796a3ee909bdde66e2f2b395 + Author: A. Jiang + Date: Wed Aug 7 18:45:41 2024 +0800 + + [func.wrap.func] Drop Lvalue-Callable + + Replace its usages with `is_invocable_r_v` and remove an unnecessary index. + + commit f9847af90413adb0436aae9f6895b4a2e0e173ec + Author: A. Jiang + Date: Mon Feb 17 11:44:11 2025 +0800 + + [containers, strings, algorithms, re] Use \range where appropriate + + Currently, there are several cases where `\tcode{[i, j)}` is used for + specifying left-closed right-open intervals, where `\range{i}{j}` is proper. + + Co-authored-by: Eelis van der Weegen + + commit 73699cf37d247a7c1f3a6879197c730a14666b90 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Feb 26 02:55:52 2021 +0300 + + [class.cdtor] Only objects of scalar type can be accessed + diff --git a/papers/wd-index.md b/papers/wd-index.md index 19b0d4c6a9..92100a86b8 100644 --- a/papers/wd-index.md +++ b/papers/wd-index.md @@ -49,3 +49,8 @@ * [N4964](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4964.pdf) 2023-10 C++ Working Draft * [N4971](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf) 2023-12 C++ Working Draft * [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 + * [N4988](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf) 2024-08 C++ Working Draft + * [N4993](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4993.pdf) 2024-10 C++ Working Draft + * [N5001](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n5001.pdf) 2024-12 C++ Working Draft + * [N5008](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf) 2025-03 C++ Working Draft diff --git a/source/algorithms.tex b/source/algorithms.tex index 58377c00dd..4c85cac4da 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -12,20 +12,20 @@ non-modifying sequence operations, mutating sequence operations, sorting and related operations, -and algorithms from the ISO C library, +and algorithms from the C library, as summarized in \tref{algorithms.summary}. \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} @@ -38,28 +38,9 @@ satisfying the assumptions on the algorithms. \pnum -The entities defined in the \tcode{std::ranges} namespace in this Clause -are not found by argument-dependent name lookup\iref{basic.lookup.argdep}. -When found by unqualified\iref{basic.lookup.unqual} name lookup -for the \grammarterm{postfix-expression} in a function call\iref{expr.call}, -they inhibit argument-dependent name lookup. - -\begin{example} -\begin{codeblock} -void foo() { - using namespace std::ranges; - std::vector vec{1,2,3}; - find(begin(vec), end(vec), 2); // \#1 -} -\end{codeblock} -The function call expression at \tcode{\#1} invokes \tcode{std::ranges::find}, -not \tcode{std::find}, despite that -(a) the iterator type returned from \tcode{begin(vec)} and \tcode{end(vec)} -may be associated with namespace \tcode{std} and -(b) \tcode{std::find} is more specialized\iref{temp.func.order} than -\tcode{std::ranges::find} since the former requires -its first two parameters to have the same type. -\end{example} +The entities defined in the \tcode{std::ranges} namespace in this Clause and +specified as function templates are +algorithm function objects\iref{alg.func.obj}. \pnum For purposes of determining the existence of data races, @@ -620,10 +601,178 @@ 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}% \begin{codeblock} +// mostly freestanding #include // see \ref{initializer.list.syn} namespace std { @@ -662,7 +811,7 @@ template constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); template - bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool all_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); namespace ranges { @@ -678,7 +827,7 @@ template constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); template - bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool any_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); namespace ranges { @@ -694,7 +843,7 @@ template constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); template - bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool none_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); namespace ranges { @@ -735,7 +884,7 @@ template constexpr Function for_each(InputIterator first, InputIterator last, Function f); template - void for_each(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void for_each(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Function f); namespace ranges { @@ -755,7 +904,7 @@ template constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); template - ForwardIterator for_each_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator for_each_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, Function f); namespace ranges { @@ -774,21 +923,21 @@ const T& value); template::value_type> - ForwardIterator find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template constexpr InputIterator find_if(InputIterator first, InputIterator last, Predicate pred); template - ForwardIterator find_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator find_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); template constexpr InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred); template - ForwardIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator find_if_not(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); @@ -854,13 +1003,13 @@ BinaryPredicate pred); template ForwardIterator1 - find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + find_end(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template ForwardIterator1 - find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + find_end(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -892,13 +1041,13 @@ BinaryPredicate pred); template ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + find_first_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + find_first_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -927,11 +1076,11 @@ BinaryPredicate pred); template ForwardIterator - adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + adjacent_find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template ForwardIterator - adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + adjacent_find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, BinaryPredicate pred); @@ -955,14 +1104,14 @@ template::value_type> typename iterator_traits::difference_type - count(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + count(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template constexpr typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); template typename iterator_traits::difference_type - count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + count_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); namespace ranges { @@ -1007,24 +1156,24 @@ BinaryPredicate pred); template pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -1062,21 +1211,21 @@ InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -1139,13 +1288,13 @@ BinaryPredicate pred); template ForwardIterator1 - search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + search(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template ForwardIterator1 - search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + search(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); @@ -1179,13 +1328,13 @@ template::value_type> ForwardIterator - search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + search_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Size count, const T& value); template::value_type, class BinaryPredicate> ForwardIterator - search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + search_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred); @@ -1296,7 +1445,7 @@ template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, @\exposconcept{indirectly-binary-right-foldable}@, I> F> requires @\libconcept{constructible_from}@, iter_reference_t> - constexpr auto fold_right_last(I first, S last, F f); + constexpr auto fold_right_last(I first, S last, F f); template<@\libconcept{bidirectional_range}@ R, @\exposconcept{indirectly-binary-right-foldable}@, iterator_t> F> @@ -1333,7 +1482,7 @@ constexpr OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); template - ForwardIterator2 copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); @@ -1356,7 +1505,7 @@ OutputIterator result); template - ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 copy_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, Size n, ForwardIterator2 result); @@ -1375,7 +1524,7 @@ OutputIterator result, Predicate pred); template - ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 copy_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); @@ -1420,7 +1569,7 @@ OutputIterator result); template - ForwardIterator2 move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 move(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); @@ -1462,7 +1611,7 @@ constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template - ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); @@ -1497,13 +1646,13 @@ template ForwardIterator2 - transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + transform(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 result, UnaryOperation op); template ForwardIterator - transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + transform(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator result, BinaryOperation binary_op); @@ -1530,14 +1679,14 @@ @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> requires @\libconcept{indirectly_writable}@, - projected>> + projected>> constexpr binary_transform_result transform(I1 first1, S1 last1, I2 first2, S2 last2, O result, F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> requires @\libconcept{indirectly_writable}@, Proj1>, - projected, Proj2>>> + projected, Proj2>>> constexpr binary_transform_result, borrowed_iterator_t, O> transform(R1&& r1, R2&& r2, O result, F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); @@ -1549,7 +1698,7 @@ const T& old_value, const T& new_value); template::value_type> - void replace(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void replace(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template::value_type> - void replace_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void replace_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); @@ -1593,7 +1742,7 @@ OutputIterator result, const T& old_value, const T& new_value); template - ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, const T& new_value); @@ -1604,7 +1753,7 @@ Predicate pred, const T& new_value); template::value_type> - ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred, const T& new_value); @@ -1654,14 +1803,14 @@ constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); template::value_type> - void fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void fill(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template::value_type> - constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); // freestanding + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value) template::value_type> - ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator fill_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, const T& value); namespace ranges { @@ -1681,13 +1830,13 @@ constexpr void generate(ForwardIterator first, ForwardIterator last, Generator gen); template - void generate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void generate(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Generator gen); template constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); template - ForwardIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator generate_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, Size n, Generator gen); namespace ranges { @@ -1708,14 +1857,14 @@ const T& value); template::value_type> - ForwardIterator remove(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator remove(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, const T& value); template constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); template - ForwardIterator remove_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator remove_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); @@ -1749,7 +1898,7 @@ template::value_type> ForwardIterator2 - remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + remove_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value); template @@ -1759,7 +1908,7 @@ template ForwardIterator2 - remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + remove_copy_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); @@ -1803,10 +1952,10 @@ constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template - ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator unique(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template - ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator unique(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, BinaryPredicate pred); @@ -1831,13 +1980,13 @@ OutputIterator result, BinaryPredicate pred); template ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + unique_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + unique_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); @@ -1867,7 +2016,7 @@ template constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); template - void reverse(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void reverse(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} BidirectionalIterator first, BidirectionalIterator last); namespace ranges { @@ -1885,7 +2034,7 @@ OutputIterator result); template ForwardIterator - reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + reverse_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} BidirectionalIterator first, BidirectionalIterator last, ForwardIterator result); @@ -1909,7 +2058,7 @@ ForwardIterator middle, ForwardIterator last); template - ForwardIterator rotate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator rotate(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator middle, ForwardIterator last); @@ -1928,7 +2077,7 @@ ForwardIterator last, OutputIterator result); template ForwardIterator2 - rotate_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + rotate_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result); @@ -1991,7 +2140,7 @@ typename iterator_traits::difference_type n); template ForwardIterator - shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + shift_left(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); @@ -2009,7 +2158,7 @@ typename iterator_traits::difference_type n); template ForwardIterator - shift_right(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + shift_right(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); @@ -2029,10 +2178,10 @@ constexpr void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template - void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last); template - void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last, Compare comp); @@ -2049,15 +2198,15 @@ } template - constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last); + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last); // hosted template - constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last, // hosted + Compare comp); template - void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void stable_sort(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last); template - void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void stable_sort(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last, Compare comp); @@ -2065,11 +2214,11 @@ template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, class Proj = identity> requires @\libconcept{sortable}@ - constexpr I stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); + constexpr I stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); // hosted template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t - stable_sort(R&& r, Comp comp = {}, Proj proj = {}); + stable_sort(R&& r, Comp comp = {}, Proj proj = {}); // hosted } template @@ -2079,11 +2228,11 @@ constexpr void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); template - void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void partial_sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); template - void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void partial_sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); @@ -2113,14 +2262,14 @@ Compare comp); template RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + partial_sort_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); template RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + partial_sort_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, @@ -2155,10 +2304,10 @@ constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); template - bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool is_sorted(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template - bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool is_sorted(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); @@ -2180,11 +2329,11 @@ Compare comp); template ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + is_sorted_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + is_sorted_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); @@ -2206,11 +2355,11 @@ constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); template - void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void nth_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); template - void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void nth_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); @@ -2326,7 +2475,7 @@ template constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); template - bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool is_partitioned(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); namespace ranges { @@ -2343,7 +2492,7 @@ ForwardIterator last, Predicate pred); template - ForwardIterator partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator partition(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Predicate pred); @@ -2361,12 +2510,12 @@ } template - constexpr BidirectionalIterator stable_partition(BidirectionalIterator first, + constexpr BidirectionalIterator stable_partition(BidirectionalIterator first, // hosted BidirectionalIterator last, Predicate pred); template - BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, + BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // hosted, + BidirectionalIterator first, // see \ref{algorithms.parallel.overloads} BidirectionalIterator last, Predicate pred); @@ -2374,11 +2523,13 @@ template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{permutable}@ - constexpr subrange stable_partition(I first, S last, Pred pred, Proj proj = {}); + constexpr subrange stable_partition(I first, S last, Pred pred, // hosted + Proj proj = {}); template<@\libconcept{bidirectional_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{permutable}@> - constexpr borrowed_subrange_t stable_partition(R&& r, Pred pred, Proj proj = {}); + constexpr borrowed_subrange_t stable_partition(R&& r, Pred pred, // hosted + Proj proj = {}); } template pair - partition_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + partition_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); @@ -2445,14 +2596,14 @@ template ForwardIterator - merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + merge(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template ForwardIterator - merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + merge(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); @@ -2477,20 +2628,20 @@ } template - constexpr void inplace_merge(BidirectionalIterator first, + constexpr void inplace_merge(BidirectionalIterator first, // hosted BidirectionalIterator middle, BidirectionalIterator last); template - constexpr void inplace_merge(BidirectionalIterator first, + constexpr void inplace_merge(BidirectionalIterator first, // hosted BidirectionalIterator middle, BidirectionalIterator last, Compare comp); template - void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void inplace_merge(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); template - void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + void inplace_merge(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); @@ -2499,12 +2650,12 @@ template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, class Proj = identity> requires @\libconcept{sortable}@ - constexpr I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); + constexpr I + inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // hosted template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, class Proj = identity> requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t - inplace_merge(R&& r, iterator_t middle, Comp comp = {}, - Proj proj = {}); + inplace_merge(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); // hosted } // \ref{alg.set.operations}, set operations @@ -2516,12 +2667,12 @@ InputIterator2 first2, InputIterator2 last2, Compare comp); template - bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool includes(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template - bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool includes(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); @@ -2548,20 +2699,20 @@ OutputIterator result); template constexpr OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, + set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template ForwardIterator - set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_union(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template ForwardIterator - set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_union(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); @@ -2598,14 +2749,14 @@ template ForwardIterator - set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_intersection(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template ForwardIterator - set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_intersection(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); @@ -2642,14 +2793,14 @@ template ForwardIterator - set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template ForwardIterator - set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); @@ -2686,14 +2837,14 @@ template ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_symmetric_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + set_symmetric_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp); @@ -2798,10 +2949,10 @@ constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template - bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool is_heap(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last); template - bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + bool is_heap(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last, Compare comp); @@ -2823,11 +2974,11 @@ Compare comp); template RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + is_heap_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last); template RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + is_heap_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} RandomAccessIterator first, RandomAccessIterator last, Compare comp); @@ -2919,10 +3070,10 @@ constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, Compare comp); template - ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator min_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template - ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator min_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); @@ -2942,10 +3093,10 @@ constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, Compare comp); template - ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator max_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template - ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator max_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); @@ -2967,11 +3118,11 @@ minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); template pair - minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + minmax_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template pair - minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + minmax_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, Compare comp); namespace ranges { @@ -3013,13 +3164,13 @@ Compare comp); template bool - lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + lexicographical_compare(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template bool - lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + lexicographical_compare(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); @@ -3766,10 +3917,12 @@ \indexlibraryglobal{find_last}% \begin{itemdecl} -template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class T, class Proj = identity> +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> requires @\libconcept{indirect_binary_predicate}@, const T*> constexpr subrange ranges::find_last(I first, S last, const T& value, Proj proj = {}); -template<@\libconcept{forward_range}@ R, class T, class Proj = identity> +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr borrowed_subrange_t ranges::find_last(R&& r, const T& value, Proj proj = {}); template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @@ -3963,7 +4116,7 @@ \pnum \complexity -At most \tcode{(last1-first1) * (last2-first2)} applications +At most \tcode{(last1 - first1) * (last2 - first2)} applications of the corresponding predicate and any projections. \end{itemdescr} @@ -4403,7 +4556,7 @@ \pnum \complexity -No applications of the corresponding predicate and projections if: +No applications of the corresponding predicate and projections if \begin{itemize} \item for the first overload, @@ -4456,7 +4609,7 @@ \begin{itemdescr} \pnum \returns -The first iterator \tcode{i} in the range \range{first1}{last1 - (last2-first2)} +The first iterator \tcode{i} in the range \crange{first1}{last1 - (last2 - first2)} such that for every non-negative integer \tcode{n} less than \tcode{last2 - first2} the following corresponding conditions hold: @@ -4494,7 +4647,7 @@ \item \tcode{\{i, i + (last2 - first2)\}}, where \tcode{i} is - the first iterator in the range \range{first1}{last1 - (last2 - first2)} + the first iterator in the range \crange{first1}{last1 - (last2 - first2)} such that for every non-negative integer \tcode{n} less than \tcode{last2 - first2} the condition @@ -4548,12 +4701,16 @@ The type \tcode{Size} is convertible to an integral type\iref{conv.integral,class.conv}. +\pnum +Let $E$ be \tcode{pred(*(i + n), value) != false} +for the overloads with a parameter \tcode{pred}, +and \tcode{*(i + n) == value} otherwise. + \pnum \returns -The first iterator \tcode{i} in the range \range{first}{last-count} +The first iterator \tcode{i} in the range \crange{first}{last - count} such that for every non-negative integer \tcode{n} less than \tcode{count} -the following corresponding conditions hold: -\tcode{*(i + n) == value, pred(*(i + n), value) != false}. +the condition $E$ is \tcode{true}. Returns \tcode{last} if no such iterator is found. \pnum @@ -4582,7 +4739,7 @@ \pnum \returns \tcode{\{i, i + count\}} -where \tcode{i} is the first iterator in the range \range{first}{last - count} +where \tcode{i} is the first iterator in the range \crange{first}{last - count} such that for every non-negative integer \tcode{n} less than \tcode{count}, the following condition holds: \tcode{invoke(pred, invoke(proj, *(i + n)), value)}. @@ -4682,7 +4839,8 @@ \returns \tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise \begin{codeblock} -ranges::equal(ranges::drop_view(ranges::ref_view(r1), N1 - N2), r2, pred, proj1, proj2) +ranges::equal(views::drop(ranges::ref_view(r1), N1 - static_cast(N2)), + r2, pred, proj1, proj2) \end{codeblock} \end{itemdescr} @@ -4904,7 +5062,7 @@ \indexlibraryglobal{copy}% \begin{itemdecl} template - ForwardIterator2 copy(ExecutionPolicy&& policy, + ForwardIterator2 copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); \end{itemdecl} @@ -5167,7 +5325,7 @@ \indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} template - ForwardIterator2 move(ExecutionPolicy&& policy, + ForwardIterator2 move(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); \end{itemdecl} @@ -5266,7 +5424,7 @@ template constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); // freestanding + ForwardIterator2 first2); template ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, @@ -5390,14 +5548,14 @@ @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> requires @\libconcept{indirectly_writable}@, - projected>> + projected>> constexpr ranges::binary_transform_result ranges::transform(I1 first1, S1 last1, I2 first2, S2 last2, O result, F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> requires @\libconcept{indirectly_writable}@, Proj1>, - projected, Proj2>>> + projected, Proj2>>> constexpr ranges::binary_transform_result, borrowed_iterator_t, O> ranges::transform(R1&& r1, R2&& r2, O result, F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); @@ -5559,14 +5717,12 @@ \indexlibraryglobal{replace_copy}% \indexlibraryglobal{replace_copy_if}% \begin{itemdecl} -template::value_type> +template constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); -template::value_type> +template ForwardIterator2 replace_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, @@ -6107,7 +6263,7 @@ \expects \begin{itemize} \item - The ranges \range{first}{last} and \range{result}{result+(last-first)} + The ranges \range{first}{last} and \range{result}{result + (last - first)} do not overlap. \item For the overloads in namespace \tcode{std}: @@ -6608,7 +6764,7 @@ from position \tcode{first + i} into position \tcode{first + n + i} for each non-negative integer \tcode{i < (last - first) - n}. Does so in order starting -from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if: +from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if \begin{itemize} \item for the overload in namespace \tcode{std} @@ -7412,7 +7568,7 @@ are partitioned with respect to the expressions \tcode{bool(invoke(comp, invoke(proj, e), value))} and \tcode{!bool(invoke(comp, value, invoke(proj, e)))}. -Also, for all elements \tcode{e} of \tcode{[first, last)}, +Also, for all elements \tcode{e} of \range{first}{last}, \tcode{bool(comp(e, value))} implies \tcode{!bool(comp(\brk{}value, e))} for the overloads in namespace \tcode{std}. @@ -7479,7 +7635,7 @@ are partitioned with respect to the expressions \tcode{bool(invoke(comp, invoke(proj, e), value))} and \tcode{!bool(invoke(comp, value, invoke(proj, e)))}. -Also, for all elements \tcode{e} of \tcode{[first, last)}, +Also, for all elements \tcode{e} of \range{first}{last}, \tcode{bool(comp(e, value))} implies \tcode{!bool(comp(\brk{}value, e))} for the overloads in namespace \tcode{std}. @@ -7945,7 +8101,7 @@ \begin{itemize} \item For the overloads with no \tcode{ExecutionPolicy}, and - if enough additional memory is available, exactly $N - 1$ comparisons. + if enough additional memory is available, at most $N - 1$ comparisons. \item Otherwise, \bigoh{N \log N} comparisons. \end{itemize} @@ -9300,7 +9456,7 @@ \tcode{ranges::lexicographical_compare(I1, S1, I2, S2, Comp, Proj1, Proj2)} can be implemented as: \begin{codeblock} -for ( ; first1 != last1 && first2 != last2 ; ++first1, (void) ++first2) { +for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { if (invoke(comp, invoke(proj1, *first1), invoke(proj2, *first2))) return true; if (invoke(comp, invoke(proj2, *first2), invoke(proj1, *first1))) return false; } @@ -9488,6 +9644,7 @@ \indexheader{numeric}% \begin{codeblock} +// mostly freestanding namespace std { // \ref{accumulate}, accumulate template @@ -9507,13 +9664,13 @@ BinaryOperation binary_op); template typename iterator_traits::value_type - reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last); template - T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + T reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, T init); template - T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + T reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); // \ref{inner.product}, inner product @@ -9541,19 +9698,19 @@ BinaryOperation binary_op, UnaryOperation unary_op); template - T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + T transform_reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init); template - T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + T transform_reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); template - T transform_reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + T transform_reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op); @@ -9578,13 +9735,13 @@ OutputIterator result, T init, BinaryOperation binary_op); template ForwardIterator2 - exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + exclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init); template ForwardIterator2 - exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + exclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op); @@ -9603,19 +9760,19 @@ OutputIterator result, BinaryOperation binary_op, T init); template ForwardIterator2 - inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template ForwardIterator2 - inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); template ForwardIterator2 - inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init); @@ -9629,7 +9786,7 @@ template ForwardIterator2 - transform_exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + transform_exclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op, UnaryOperation unary_op); @@ -9650,14 +9807,14 @@ template ForwardIterator2 - transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + transform_inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op); template ForwardIterator2 - transform_inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + transform_inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init); @@ -9673,13 +9830,13 @@ OutputIterator result, BinaryOperation binary_op); template ForwardIterator2 - adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + adjacent_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template ForwardIterator2 - adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + adjacent_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); @@ -9715,15 +9872,15 @@ // \ref{numeric.sat}, saturation arithmetic template - constexpr T add_sat(T x, T y) noexcept; // freestanding + constexpr T add_sat(T x, T y) noexcept; template - constexpr T sub_sat(T x, T y) noexcept; // freestanding + constexpr T sub_sat(T x, T y) noexcept; template - constexpr T mul_sat(T x, T y) noexcept; // freestanding + constexpr T mul_sat(T x, T y) noexcept; template - constexpr T div_sat(T x, T y) noexcept; // freestanding + constexpr T div_sat(T x, T y) noexcept; template - constexpr T saturate_cast(U x) noexcept; // freestanding + constexpr T saturate_cast(U x) noexcept; } \end{codeblock} @@ -10665,7 +10822,7 @@ \pnum For the overloads with an \tcode{ExecutionPolicy} and a non-empty range, performs \tcode{*result = *first}. -Then, for every \tcode{d} in \tcode{[1, last - first - 1]}, +Then, for every \tcode{d} in \crange{1}{last - first - 1}, performs \tcode{*(result + d) = binary_op(*(first + d), *(first + (d - 1)))}. \pnum @@ -10984,15 +11141,31 @@ are destroyed in an unspecified order before allowing the exception to propagate. +\pnum +\begin{note} +When new objects are created by +the algorithms specified in \ref{specialized.algorithms}, +the lifetime ends for any existing objects +(including potentially-overlapping subobjects \ref{intro.object}) +in storage that is reused \ref{basic.life}. +\end{note} + \pnum Some algorithms specified in \ref{specialized.algorithms} -make use of the exposition-only function template -\tcode{\placeholdernc{voidify}}: +make use of the following exposition-only function templates: \begin{codeblock} template constexpr void* @\placeholdernc{voidify}@(T& obj) noexcept { return addressof(obj); } + +template + decltype(auto) @\exposid{deref-move}@(I& it) { + if constexpr (is_lvalue_reference_v) + return std::move(*it); + else + return *it; + } \end{codeblock} \rSec2[special.mem.concepts]{Special memory concepts} @@ -11086,7 +11259,8 @@ \indexlibraryglobal{uninitialized_default_construct}% \begin{itemdecl} template - void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); + constexpr void uninitialized_default_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); \end{itemdecl} \begin{itemdescr} @@ -11105,10 +11279,10 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct(I first, S last); + constexpr I uninitialized_default_construct(I first, S last); template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_default_construct(R&& r); + constexpr borrowed_iterator_t uninitialized_default_construct(R&& r); } \end{itemdecl} @@ -11126,7 +11300,8 @@ \indexlibraryglobal{uninitialized_default_construct_n}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); + constexpr NoThrowForwardIterator + uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); \end{itemdecl} \begin{itemdescr} @@ -11146,7 +11321,7 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct_n(I first, iter_difference_t n); + constexpr I uninitialized_default_construct_n(I first, iter_difference_t n); } \end{itemdecl} @@ -11165,7 +11340,8 @@ \indexlibraryglobal{uninitialized_value_construct}% \begin{itemdecl} template - void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); + constexpr void uninitialized_value_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); \end{itemdecl} \begin{itemdescr} @@ -11184,10 +11360,10 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct(I first, S last); + constexpr I uninitialized_value_construct(I first, S last); template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_value_construct(R&& r); + constexpr borrowed_iterator_t uninitialized_value_construct(R&& r); } \end{itemdecl} @@ -11205,7 +11381,8 @@ \indexlibraryglobal{uninitialized_value_construct_n}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); + constexpr NoThrowForwardIterator + uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); \end{itemdecl} \begin{itemdescr} @@ -11225,7 +11402,7 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct_n(I first, iter_difference_t n); + constexpr I uninitialized_value_construct_n(I first, iter_difference_t n); } \end{itemdecl} @@ -11244,8 +11421,8 @@ \indexlibraryglobal{uninitialized_copy}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, + NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} @@ -11257,7 +11434,7 @@ \effects Equivalent to: \begin{codeblock} -for (; first != last; ++result, (void) ++first) +for (; first != last; ++result, (void)++first) ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(*first); \end{codeblock} @@ -11273,11 +11450,11 @@ template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_reference_t> - uninitialized_copy_result + constexpr uninitialized_copy_result uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_reference_t> - uninitialized_copy_result, borrowed_iterator_t> + constexpr uninitialized_copy_result, borrowed_iterator_t> uninitialized_copy(IR&& in_range, OR&& out_range); } \end{itemdecl} @@ -11300,8 +11477,8 @@ \indexlibraryglobal{uninitialized_copy_n}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, + NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} @@ -11313,7 +11490,7 @@ \effects Equivalent to: \begin{codeblock} -for ( ; n > 0; ++result, (void) ++first, --n) +for (; n > 0; ++result, (void)++first, --n) ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(*first); \end{codeblock} @@ -11328,7 +11505,7 @@ namespace ranges { template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_reference_t> - uninitialized_copy_n_result + constexpr uninitialized_copy_n_result uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); } \end{itemdecl} @@ -11354,8 +11531,8 @@ \indexlibraryglobal{uninitialized_move}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, + NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} @@ -11369,7 +11546,7 @@ \begin{codeblock} for (; first != last; (void)++result, ++first) ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(std::move(*first)); + typename iterator_traits::value_type(@\exposid{deref-move}@(first)); return result; \end{codeblock} \end{itemdescr} @@ -11380,11 +11557,11 @@ template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> - uninitialized_move_result + constexpr uninitialized_move_result uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_rvalue_reference_t> - uninitialized_move_result, borrowed_iterator_t> + constexpr uninitialized_move_result, borrowed_iterator_t> uninitialized_move(IR&& in_range, OR&& out_range); } \end{itemdecl} @@ -11414,7 +11591,7 @@ \indexlibraryglobal{uninitialized_move_n}% \begin{itemdecl} template - pair + constexpr pair uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); \end{itemdecl} @@ -11427,9 +11604,9 @@ \effects Equivalent to: \begin{codeblock} -for (; n > 0; ++result, (void) ++first, --n) +for (; n > 0; ++result, (void)++first, --n) ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(std::move(*first)); + typename iterator_traits::value_type(@\exposid{deref-move}@(first)); return {first, result}; \end{codeblock} \end{itemdescr} @@ -11439,7 +11616,7 @@ namespace ranges { template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> - uninitialized_move_n_result + constexpr uninitialized_move_n_result uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); } \end{itemdecl} @@ -11471,7 +11648,8 @@ \indexlibraryglobal{uninitialized_fill}% \begin{itemdecl} template - void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); + constexpr void uninitialized_fill(NoThrowForwardIterator first, + NoThrowForwardIterator last, const T& x); \end{itemdecl} \begin{itemdescr} @@ -11490,10 +11668,10 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill(I first, S last, const T& x); + constexpr I uninitialized_fill(I first, S last, const T& x); template<@\exposconcept{nothrow-forward-range}@ R, class T> requires @\libconcept{constructible_from}@, const T&> - borrowed_iterator_t uninitialized_fill(R&& r, const T& x); + constexpr borrowed_iterator_t uninitialized_fill(R&& r, const T& x); } \end{itemdecl} @@ -11511,7 +11689,8 @@ \indexlibraryglobal{uninitialized_fill_n}% \begin{itemdecl} template - NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); + constexpr NoThrowForwardIterator + uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); \end{itemdecl} \begin{itemdescr} @@ -11531,7 +11710,7 @@ namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill_n(I first, iter_difference_t n, const T& x); + constexpr I uninitialized_fill_n(I first, iter_difference_t n, const T& x); } \end{itemdecl} @@ -11560,14 +11739,22 @@ \begin{itemdescr} \pnum \constraints -The expression \tcode{::new (declval()) T(declval()...)} +\tcode{is_unbounded_array_v} is \tcode{false}. +The expression \tcode{::new (declval()) T(\linebreak{}declval()...)} is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}. +\pnum +\mandates +If \tcode{is_array_v} is \tcode{true}, \tcode{sizeof...(Args)} is zero. + \pnum \effects Equivalent to: \begin{codeblock} -return ::new (@\placeholdernc{voidify}@(*location)) T(std::forward(args)...); +if constexpr (is_array_v) + return ::new (@\placeholdernc{voidify}@(*location)) T[1](); +else + return ::new (@\placeholdernc{voidify}@(*location)) T(std::forward(args)...); \end{codeblock} \end{itemdescr} @@ -11678,6 +11865,7 @@ \rSec2[alg.rand.generate]{\tcode{generate_random}} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template requires @\libconcept{output_range}@> && @\libconcept{uniform_random_bit_generator}@> @@ -11720,6 +11908,7 @@ \end{note} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template> O, @\libconcept{sentinel_for}@ S> requires @\libconcept{uniform_random_bit_generator}@> @@ -11735,10 +11924,12 @@ \end{codeblock} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template requires @\libconcept{output_range}@> && @\libconcept{invocable}@ && - @\libconcept{uniform_random_bit_generator}@> + @\libconcept{uniform_random_bit_generator}@> && + is_arithmetic_v> constexpr borrowed_iterator_t ranges::generate_random(R&& r, G&& g, D&& d); \end{itemdecl} @@ -11770,7 +11961,7 @@ \pnum \returns -\tcode{ranges::end(r)} +\tcode{ranges::end(r)}. \pnum \remarks @@ -11785,9 +11976,11 @@ \end{note} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template> O, @\libconcept{sentinel_for}@ S> - requires @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> + requires @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> && + is_arithmetic_v> constexpr O ranges::generate_random(O first, S last, G&& g, D&& d); \end{itemdecl} diff --git a/source/assets/iso-logo-caution.png b/source/assets/iso-logo-caution.png new file mode 100644 index 0000000000..49b12792b8 Binary files /dev/null and b/source/assets/iso-logo-caution.png differ diff --git a/source/back.tex b/source/back.tex index 4d9a27a1ec..7cd2714e9f 100644 --- a/source/back.tex +++ b/source/back.tex @@ -1,5 +1,7 @@ %!TEX root = std.tex +\renewcommand{\leftmark}{\bibname} + \begin{thebibliography}{99} % ISO documents in numerical order. \bibitem{iso4217} @@ -9,6 +11,24 @@ ISO/IEC 10967-1:2012, \doccite{Information technology --- Language independent arithmetic --- Part 1: Integer and floating point arithmetic} +\bibitem{iso14882:2023} + ISO/IEC 14882:2023, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2020} + ISO/IEC 14882:2020, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2017} + ISO/IEC 14882:2017, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2014} + ISO/IEC 14882:2014, + \doccite{Information technology --- Programming Languages --- \Cpp{}} +\bibitem{iso14882:2011} + ISO/IEC 14882:2011, + \doccite{Information technology --- Programming Languages --- \Cpp{}} +\bibitem{iso14882:2003} + ISO/IEC 14882:2003, + \doccite{Programming Languages --- \Cpp{}} \bibitem{iso18661-3} ISO/IEC TS 18661-3:2015, \doccite{Information Technology --- @@ -32,13 +52,13 @@ \doccite{The \Cpp{} Programming Language, second edition}, Chapter R\@. Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright \copyright 1991 AT\&T \bibitem{kr} - Brian W.\ Kernighan and Dennis M. Ritchie, + Brian W.\ Kernighan and Dennis M.\ Ritchie, \doccite{The C Programming Language}, Appendix A\@. Prentice-Hall, 1978, ISBN 0-13-110163-3, copyright \copyright 1978 AT\&T \bibitem{cpp-lib} - P.J.\ Plauger, + P.\,J.\ Plauger, \doccite{The Draft Standard \Cpp{} Library}. - Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.J.\ Plauger + Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.\,J.\ Plauger \bibitem{linalg-stable} J.\ Demmel, I.\ Dumitriu, and O.\ Holtz, \doccite{Fast linear algebra is stable}, @@ -48,7 +68,7 @@ \doccite{Basic linear algebra subprograms for Fortran usage}. ACM Trans.\ Math.\ Soft., Vol.\ 5, pp.\ 308--323, 1979. \bibitem{blas2} - Jack J.\ Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard J. Hanson, + Jack J.\ Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard J.\ Hanson, \doccite{An Extended Set of FORTRAN Basic Linear Algebra Subprograms}. ACM Trans.\ Math.\ Soft., Vol.\ 14, No.\ 1, pp.\ 1--17, Mar.\ 1988. \bibitem{blas3} @@ -57,20 +77,21 @@ ACM Trans.\ Math.\ Soft., Vol.\ 16, No.\ 1, pp.\ 1--17, Mar.\ 1990. \bibitem{lapack} E.\ Anderson, Z.\ Bai, C.\ Bischof, S.\ Blackford, J.\ Demmel, J.\ Dongarra, - J.\ Du Croz, A.\ Greenbaum, S.\ Hammarling, A.\ McKenney, D.\ Sorensen + J.\ Du Croz, A.\ Greenbaum, S.\ Hammarling, A.\ McKenney, and D.\ Sorensen, \doccite{LAPACK Users' Guide, Third Edition}. SIAM, Philadelphia, PA, USA, 1999. \bibitem{blas-std} - L. Susan Blackford, Ames Demmel, Jack Dongarra, Iain Duff, Sven Hammarling, + L.\ Susan Blackford, James Demmel, Jack Dongarra, Iain Duff, Sven Hammarling, Greg Henry, Michael Heroux, Linda Kaufman, Andrew Lumbsdaine, Antoine Petitet, - Roldan Pozo, Karin Remington, R. Client Whaley + Roldan Pozo, Karin Remington, and R.\ Client Whaley, \doccite{An Updated Set of Basic Linear Algebra Subprograms (BLAS)}. ACM Trans.\ Math.\ Soft., Vol.\ 28, Issue 2, 2002. +\bibitem{flynn-taxonomy} + Michael J.\ Flynn, + \doccite{Very High-Speed Computing Systems}. + Proceedings of the IEEE, Vol.\ 54, Issue 12, 1966. \end{thebibliography} -The arithmetic specification described in ISO/IEC 10967-1:2012 is -called \defn{LIA-1} in this document. - % FIXME: For unknown reasons, hanging paragraphs are not indented within our % glossaries by default. \let\realglossitem\glossitem @@ -89,9 +110,9 @@ \clearpage \input{xrefdelta} -\renewcommand{\glossaryname}{Cross-references from ISO \CppXXIII{}} +\renewcommand{\glossaryname}{Cross-references from ISO \CppXVII{}} \renewcommand{\preglossaryhook}{All clause and subclause labels from -ISO \CppXXIII{} (ISO/IEC 14882:2023, \doccite{Programming Languages --- \Cpp{}}) +ISO \CppXVII{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}) are present in this document, with the exceptions described below.\\} \renewcommand{\leftmark}{\glossaryname} { @@ -144,7 +165,6 @@ \clearpage \renewcommand{\preindexhook}{The entries in this index are rough descriptions; exact specifications are at the indicated page in the general text.\\} -\renewcommand{\leftmark}{Index of impl.-def. behavior} { \raggedright \printindex[impldefindex] diff --git a/source/basic.tex b/source/basic.tex index f33d0dc648..2edf6dd134 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4,6 +4,11 @@ \gramSec[gram.basic]{Basics} \rSec1[basic.pre]{Preamble} +\indextext{type}% +\indextext{object}% +\indextext{storage class}% +\indextext{scope}% +\indextext{linkage}% \pnum \begin{note} @@ -27,22 +32,22 @@ \end{note} \pnum -\indextext{type}% -\indextext{object}% -\indextext{storage class}% -\indextext{scope}% -\indextext{linkage}% -An \defn{entity} is a value, object, reference, -structured binding, -function, enumerator, type, -class member, bit-field, template, template specialization, namespace, or -pack. +A \defn{name} is an \grammarterm{identifier}\iref{lex.name}, +\grammarterm{conversion-function-id}\iref{class.conv.fct}, +\grammarterm{operator-function-id}\iref{over.oper}, or +\grammarterm{literal-operator-id}\iref{over.literal}. \pnum -A \defn{name} is an \grammarterm{identifier}\iref{lex.name}, -\grammarterm{operator-function-id}\iref{over.oper}, -\grammarterm{literal-operator-id}\iref{over.literal}, or -\grammarterm{conversion-function-id}\iref{class.conv.fct}. +Two names are \defnx{the same}{name!same} if +\begin{itemize} +\item they are \grammarterm{identifier}{s} composed of the same character sequence, or +\item they are \grammarterm{conversion-function-id}{s} formed with +equivalent\iref{temp.over.link} types, or +\item they are \grammarterm{operator-function-id}{s} formed with +the same operator, or +\item they are \grammarterm{literal-operator-id}{s} formed with +the same literal suffix identifier. +\end{itemize} \pnum Every name is introduced by a \defn{declaration}, which is a @@ -57,6 +62,10 @@ \grammarterm{identifier} in a structured binding declaration\iref{dcl.struct.bind}, \item +\grammarterm{identifier} +in a \grammarterm{result-name-introducer} +in a postcondition assertion\iref{dcl.contract.res}, +\item \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, \item \grammarterm{condition} with a \grammarterm{declarator}\iref{stmt.pre}, @@ -65,10 +74,16 @@ \item \grammarterm{using-declarator}\iref{namespace.udecl}, \item -\grammarterm{parameter-declaration}\iref{dcl.fct}, +\grammarterm{parameter-declaration}\iref{dcl.fct,temp.param}, \item \grammarterm{type-parameter}\iref{temp.param}, \item +\grammarterm{type-tt-parameter}\iref{temp.param}, +\item +\grammarterm{variable-tt-parameter}\iref{temp.param}, +\item +\grammarterm{concept-tt-parameter}\iref{temp.param}, +\item \grammarterm{elaborated-type-specifier} that introduces a name\iref{dcl.type.elab}, \item @@ -85,9 +100,15 @@ The interpretation of a \grammarterm{for-range-declaration} produces one or more of the above\iref{stmt.ranged}. \end{note} -An entity $E$ is denoted by the name (if any) -that is introduced by a declaration of $E$ or -by a \grammarterm{typedef-name} introduced by a declaration specifying $E$. + +\pnum +\begin{note} +Some names denote types or templates. +In general, whenever a name is encountered +it is necessary to look it up\iref{basic.lookup} +to determine whether that name denotes one of these entities +before continuing to parse the program that contains it. +\end{note} \pnum A \defn{variable} is introduced by the @@ -95,32 +116,24 @@ a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object. +\pnum +An \defn{entity} is a value, object, reference, +structured binding, +result binding, +function, enumerator, type, +class member, bit-field, template, template specialization, namespace, or +pack. An entity $E$ is denoted by the name (if any) +that is introduced by a declaration of $E$ or +by a \grammarterm{typedef-name} introduced by a declaration specifying $E$. + \pnum A \defnadj{local}{entity} is a variable with automatic storage duration\iref{basic.stc.auto}, a structured binding\iref{dcl.struct.bind} whose corresponding variable is such an entity, +a result binding\iref{dcl.contract.res}, or the \tcode{*\keyword{this}} object\iref{expr.prim.this}. -\pnum -Some names denote types or templates. In general, -whenever a name is encountered it is necessary to determine whether that name denotes -one of these entities before continuing to parse the program that contains it. The -process that determines this is called -\defnx{name lookup}{lookup!name}\iref{basic.lookup}. - -\pnum -Two names are \defnx{the same}{name!same} if -\begin{itemize} -\item they are \grammarterm{identifier}{s} composed of the same character sequence, or -\item they are \grammarterm{operator-function-id}{s} formed with -the same operator, or -\item they are \grammarterm{conversion-function-id}{s} formed -with equivalent\iref{temp.over.link} types, or -\item they are \grammarterm{literal-operator-id}{s}\iref{over.literal} formed with -the same literal suffix identifier. -\end{itemize} - \pnum \indextext{translation unit!name and}% \indextext{linkage}% @@ -135,14 +148,15 @@ \indextext{declaration!definition versus}% \indextext{declaration}% \indextext{declaration!name}% -A declaration\iref{dcl.dcl} may (re)introduce +A declaration\iref{dcl} may (re)introduce one or more names and/or entities into a translation unit. If so, the declaration specifies the interpretation and semantic properties of these names. A declaration of an entity or \grammarterm{typedef-name} $X$ is a redeclaration of $X$ -if another declaration of $X$ is reachable from it\iref{module.reach}. +if another declaration of $X$ is reachable from it\iref{module.reach}; +otherwise, it is a \defnadj{first}{declaration}. A declaration may also have effects including: \begin{itemize} \item a static assertion\iref{dcl.pre}, @@ -299,10 +313,10 @@ C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast(x.s)) { } - @\rlap{\normalfont\itshape //}@ : s(std::move(x.s)) { } + @\rlap{\textnormal{\textit{//}}}@ : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast(x.s); return *this; } - @\rlap{\normalfont\itshape //}@ { s = std::move(x.s); return *this; } + @\rlap{\textnormal{\textit{//}}}@ { s = std::move(x.s); return *this; } ~C() { } }; \end{codeblock} @@ -441,24 +455,59 @@ A variable is named by an expression if the expression is an \grammarterm{id-expression} that denotes it. A variable \tcode{x} that is named by a -potentially-evaluated expression $E$ -is \defnx{odr-used}{odr-use} by $E$ unless +potentially-evaluated expression $N$ +that appears at a point $P$ +is \defnx{odr-used}{odr-use} by $N$ unless +\begin{itemize} +\item +\tcode{x} is a reference +that is usable in constant expressions at $P$\iref{expr.const} or +\item +$N$ is an element of the set of potential results of an expression $E$, where \begin{itemize} \item - \tcode{x} is a reference that is - usable in constant expressions\iref{expr.const}, or +$E$ is a discarded-value expression\iref{expr.context} +to which the lvalue-to-rvalue conversion is not applied or \item - \tcode{x} is a variable of non-reference type that is - usable in constant expressions and has no mutable subobjects, and - $E$ is an element of the set of potential results of an expression - of non-volatile-qualified non-class type - to which the lvalue-to-rvalue conversion\iref{conv.lval} is applied, or +\tcode{x} is a non-volatile object +that is usable in constant expressions at $P$ and +has no mutable subobjects and +\begin{itemize} +\item +$E$ is a class member access expression\iref{expr.ref} +naming a non-static data member of reference type and +whose object expression has non-volatile-qualified type or \item - \tcode{x} is a variable of non-reference type, and - $E$ is an element of the set of potential results - of a discarded-value expression\iref{expr.context} - to which the lvalue-to-rvalue conversion is not applied. +the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and +$E$ has non-volatile-qualified non-class type +\end{itemize} +\end{itemize} \end{itemize} +\begin{example} +\begin{codeblock} +int f(int); +int g(int&); +struct A { + int x; +}; +struct B { + int& r; +}; +int h(bool cond) { + constexpr A a = {1}; + constexpr const volatile A& r = a; // odr-uses \tcode{a} + int _ = f(cond ? a.x : r.x); // does not odr-use \tcode{a} or \tcode{r} + int x, y; + constexpr B b1 = {x}, b2 = {y}; // odr-uses \tcode{x} and \tcode{y} + int _ = g(cond ? b1.r : b2.r); // does not odr-use \tcode{b1} or \tcode{b2} + int _ = ((cond ? x : y), 0); // does not odr-use \tcode{x} or \tcode{y} + return [] { + return b1.r; // error: \tcode{b1} is odr-used here because the object + // referred to by \tcode{b1.r} is not constexpr-referenceable here + }(); +} +\end{codeblock} +\end{example} \pnum A structured binding is odr-used if it appears as a potentially-evaluated expression. @@ -497,7 +546,7 @@ \pnum A local entity\iref{basic.pre} -is \defn{odr-usable} in a scope\iref{basic.scope.scope} if: +is \defn{odr-usable} in a scope\iref{basic.scope.scope} if \begin{itemize} \item either the local entity is not \tcode{*\keyword{this}}, or an enclosing class or non-lambda function parameter scope exists and, @@ -508,10 +557,14 @@ between the point at which the entity is introduced and the scope (where \tcode{*\keyword{this}} is considered to be introduced within the innermost enclosing class or non-lambda function definition scope), -either: +either \begin{itemize} -\item the intervening scope is a block scope, or -\item the intervening scope is the function parameter scope of a \grammarterm{lambda-expression} +\item the intervening scope is a block scope, +\item the intervening scope is a contract-assertion scope\iref{basic.scope.contract}, +\item the intervening scope is the function parameter scope of +a \grammarterm{lambda-expression} or \grammarterm{requires-expression}, or +\item the intervening scope is the lambda scope of +a \grammarterm{lambda-expression} that has a \grammarterm{simple-capture} naming the entity or has a \grammarterm{capture-default}, and the block scope of the \grammarterm{lambda-expression} @@ -607,7 +660,7 @@ \begin{note} The rules for declarations and expressions describe in which contexts complete class types are required. A class -type \tcode{T} must be complete if: +type \tcode{T} must be complete if \begin{itemize} \item an object of type \tcode{T} is defined\iref{basic.def}, or \item a non-static class data member of type \tcode{T} is @@ -634,7 +687,7 @@ is defined\iref{basic.def} or called\iref{expr.call}, or \item a class with a base class of type \tcode{T} is defined\iref{class.derived}, or -\item an lvalue of type \tcode{T} is assigned to\iref{expr.ass}, or +\item an lvalue of type \tcode{T} is assigned to\iref{expr.assign}, or \item the type \tcode{T} is the subject of an \keyword{alignof} expression\iref{expr.alignof}, or \item an \grammarterm{exception-declaration} has type \tcode{T}, reference to @@ -671,7 +724,7 @@ \item In each such definition, corresponding names, looked up according to~\ref{basic.lookup}, shall refer to the same entity, after overload resolution\iref{over.match} and after matching of partial -template specialization\iref{temp.over}, except that a name can refer to +template specializations\iref{temp.spec.partial.match}, except that a name can refer to \begin{itemize} \item a non-volatile const object with internal or no linkage if the object @@ -844,9 +897,11 @@ every other scope $S$ is introduced by a declaration, \grammarterm{parameter-declaration-clause}, -\grammarterm{statement}, or \grammarterm{handler} +\grammarterm{statement}, +\grammarterm{handler}, or +contract assertion (as described in the following subclauses of \ref{basic.scope}) -appearing in another scope which thereby contains $S$. +appearing in another scope, which thereby contains $S$. An \defnadj{enclosing}{scope} at a program point is any scope that contains it; the smallest such scope is said to be the \defnadj{immediate}{scope} at that point. @@ -887,15 +942,14 @@ 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} target a larger enclosing scope. \item -Block-scope extern declarations target a larger enclosing scope -but bind a name in their immediate scope. +Block-scope extern or function declarations target a larger enclosing scope +but bind a name in their immediate scope\iref{dcl.meaning.general}. \item The names of unscoped enumerators are bound in the two innermost enclosing scopes\iref{dcl.enum}. @@ -909,20 +963,20 @@ \pnum Two non-static member functions have -\defnadjx{corresponding}{object parameters}{object parameter} if: +\defnadjx{corresponding}{object parameters}{object parameter} if \begin{itemize} \item exactly one is an implicit object member function with no \grammarterm{ref-qualifier} and the types of their object parameters\iref{dcl.fct}, -after removing top-level references, +after removing references, are the same, or \item their object parameters have the same type. \end{itemize} \indextext{template!function!corresponding object parameter}% Two non-static member function templates have -\defnadjx{corresponding}{object parameters}{object parameter} if: +\defnadjx{corresponding}{object parameters}{object parameter} if \begin{itemize} \item exactly one is an implicit object member function @@ -963,7 +1017,7 @@ and they do not declare corresponding overloads. \end{itemize} Two function or function template declarations declare -\defn{corresponding overloads} if: +\defn{corresponding overloads} if \begin{itemize} \item both declare functions with the same non-object-parameter-type-list, @@ -1032,6 +1086,8 @@ with no \grammarterm{storage-class-specifier} and not inhabiting a namespace scope, \item +a result binding\iref{dcl.contract.res}, +\item the variable introduced by an \grammarterm{init-capture}, or \item %FIXME: "of" is strange below; remove it? @@ -1237,6 +1293,10 @@ \end{codeblock} \end{example} +\pnum +The locus of a \grammarterm{result-name-introducer}\iref{dcl.contract.res} +is immediately after it. + \pnum The locus of a \grammarterm{concept-definition} is immediately after its \grammarterm{concept-name}\iref{temp.concept}. @@ -1452,7 +1512,11 @@ \rSec2[basic.scope.temp]{Template parameter scope}% \pnum -Each template \grammarterm{template-parameter} introduces +Each +\grammarterm{type-tt-parameter}, +\grammarterm{variable-tt-parameter}, and +\grammarterm{concept-tt-parameter} +introduces a \defnadj{template parameter}{scope} that includes the \grammarterm{template-head} of the \grammarterm{template-parameter}. @@ -1472,6 +1536,30 @@ a template parameter scope as a parent scope. \end{note} +\rSec2[basic.scope.contract]{Contract-assertion scope}% + +\pnum +Each contract assertion\iref{basic.contract} +$C$ introduces a \defnadj{contract-assertion}{scope} +that includes $C$. + +\pnum +If a \grammarterm{result-name-introducer}\iref{dcl.contract.res} +that is not name-independent\iref{basic.scope.scope} +and whose enclosing postcondition assertion +is associated with a function \tcode{F} +potentially conflicts with +a declaration whose target scope is +\begin{itemize} +\item +the function parameter scope of \tcode{F} or +\item +if associated with a \grammarterm{lambda-declarator}, +the nearest enclosing lambda scope +of the precondition assertion\iref{expr.prim.lambda}, +\end{itemize} +the program is ill-formed. + \indextext{scope|)} \rSec1[basic.lookup]{Name lookup}% @@ -1482,13 +1570,13 @@ \indextext{scope!name lookup and|see{lookup, name}}% \pnum +\defnx{Name lookup}{lookup!name} associates the use of a name +with a set of declarations\iref{basic.def} of that name. The name lookup rules apply uniformly to all names (including \grammarterm{typedef-name}{s}\iref{dcl.typedef}, \grammarterm{namespace-name}{s}\iref{basic.namespace}, and \grammarterm{class-name}{s}\iref{class.name}) wherever the grammar allows -such names in the context discussed by a particular rule. Name lookup -associates the use of a name with a set of declarations\iref{basic.def} of -that name. +such names in the context discussed by a particular rule. Unless otherwise specified, the program is ill-formed if no declarations are found. If the declarations found by name lookup @@ -1973,7 +2061,7 @@ then lookup for the name also includes the result of \defnadj{argument-dependent}{lookup} in a set of associated namespaces that depends on the types of the arguments -(and for template template arguments, the namespace of the template argument), +(and for type template template arguments, the namespace of the template argument), as specified below. \begin{example} \begin{codeblock} @@ -2041,7 +2129,7 @@ to be considered. The set of entities is determined entirely by the types of the function arguments -(and any template template arguments). +(and any type template template arguments). Any \grammarterm{typedef-name}s and \grammarterm{using-declaration}{s} used to specify the types do not contribute to this set. @@ -2061,11 +2149,14 @@ the entities associated with the types of the template arguments provided for template type parameters; -the templates used as template template arguments; and -the classes of which any member templates used as template template +the templates used as type template template arguments; and +the classes of which any member templates used as type template template arguments are members. \begin{note} -Non-type template arguments do not +Constant template arguments, +variable template template arguments, and +concept template arguments +do not contribute to the set of associated entities. \end{note} @@ -2096,8 +2187,8 @@ parameter types and return type. Additionally, if the aforementioned overload set is named with a \grammarterm{template-id}, its associated entities also include -its template \grammarterm{template-argument}{s} and -those associated with its type \grammarterm{template-argument}s. +its template template arguments and +those associated with its type template arguments. \pnum The \term{associated namespaces} for a call are @@ -2652,6 +2743,7 @@ \pnum \indextext{program}% +\indextext{linking}% A \defn{program} consists of one or more translation units\iref{lex.separate} linked together. A translation unit consists of a sequence of declarations. @@ -2664,28 +2756,18 @@ \pnum \indextext{translation unit}% -A name is said to have \defn{linkage} when it can denote the same -object, reference, function, type, template, namespace or value as a -name introduced by a declaration in another scope: -\begin{itemize} -\item When a name has \defnadj{external}{linkage}, -the entity it denotes -can be referred to by names from scopes of other translation units or -from other scopes of the same translation unit. - -\item When a name has \defnx{module linkage}{linkage!module}, -the entity it denotes -can be referred to by names from other scopes of the same module unit\iref{module.unit} or -from scopes of other module units of that same module. - -\item When a name has \defnadj{internal}{linkage}, -the entity it denotes -can be referred to by names from other scopes in the same translation -unit. - -\item When a name has \indextext{linkage!no}\defn{no linkage}, the entity it denotes -cannot be referred to by names from other scopes. -\end{itemize} +A name can have +\defnadj{external}{linkage}, +\defnadj{module}{linkage}, +\defnadj{internal}{linkage}, or +\defnadj{no}{linkage}, +as determined by the rules below. +\begin{note} +All declarations of an entity with a name with internal linkage +appear in the same translation unit. +All declarations of an entity with module linkage +are attached to the same module. +\end{note} \pnum \indextext{linkage!\idxcode{static} and}% @@ -2723,8 +2805,8 @@ \pnum An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. -The name of an entity that belongs to a namespace scope -that has not been given internal linkage above +The name of an entity that belongs to a namespace scope, +that has not been given internal linkage above, and that is the name of \begin{itemize} \item a variable; or @@ -2746,6 +2828,24 @@ has its linkage determined as follows: \begin{itemize} \item +\indextext{friend function!linkage of}% +if the entity is a function or function template +first declared in a friend declaration and +that declaration is a definition and +the enclosing class is defined within an \grammarterm{export-declaration}, +the name has the same linkage, if any, +as the name of the enclosing class\iref{class.friend}; +\item +otherwise, +\indextext{friend function!linkage of}% +if the entity is a function or function template +declared in a friend declaration and +a corresponding non-friend declaration is reachable, +%FIXME: Which declaration is "that prior declaration"? +%FIXME: "prior" with respect to what? And what about dependent lookup? +the name has the linkage determined from that prior declaration, +\item +otherwise, if the enclosing namespace has internal linkage, the name has internal linkage; \item @@ -3086,11 +3186,6 @@ \indextext{character set!basic literal}% literal character set\iref{lex.charset} and the eight-bit code units of the Unicode -\begin{footnote} -Unicode\textregistered\ is a registered trademark of Unicode, Inc. -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} \indextext{UTF-8}% UTF-8 encoding form and is composed of a contiguous sequence of @@ -3099,11 +3194,10 @@ The number of bits in a byte is reported by the macro \tcode{CHAR_BIT} in the header \libheaderref{climits}. \end{footnote} -the number of which is \impldef{bits in a byte}. The least -significant bit is called the \defn{low-order bit}; the most -significant bit is called the \defn{high-order bit}. The memory -available to a \Cpp{} program consists of one or more sequences of -contiguous bytes. Every byte has a unique address. +the number of which is \impldef{bits in a byte}. +The memory available to a \Cpp{} program consists of one or more sequences of +contiguous bytes. +Every byte has a unique address. \pnum \begin{note} @@ -3112,7 +3206,9 @@ \end{note} \pnum -A \defn{memory location} is either an object of scalar type that is not a bit-field +A \defn{memory location} is +the storage occupied by the object representation of +either an object of scalar type that is not a bit-field or a maximal sequence of adjacent bit-fields all having nonzero width. \begin{note} Various @@ -3206,7 +3302,7 @@ in storage associated with a member subobject or array element \placeholder{e} (which may or may not be within its lifetime), the created object -is a subobject of \placeholder{e}'s containing object if: +is a subobject of \placeholder{e}'s containing object if \begin{itemize} \item the lifetime of \placeholder{e}'s containing object has begun and not ended, and @@ -3223,7 +3319,7 @@ of type ``array of $N$ \tcode{\keyword{unsigned} \keyword{char}}'' or of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, that array \defn{provides storage} -for the created object if: +for the created object if \begin{itemize} \item the lifetime of \placeholder{e} has begun and not ended, and @@ -3266,7 +3362,7 @@ \pnum \indextext{object!nested within}% -An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if: +An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if \begin{itemize} \item \placeholder{a} is a subobject of \placeholder{b}, or @@ -3432,13 +3528,15 @@ \end{example} \pnum -An operation that begins the lifetime of +Except during constant evaluation, +an operation that begins the lifetime of an array of \tcode{unsigned char} or \tcode{std::byte} implicitly creates objects within the region of storage occupied by the array. \begin{note} The array object provides storage for these objects. \end{note} -Any implicit or explicit invocation of a function +Except during constant evaluation, +any implicit or explicit invocation of a function named \tcode{\keyword{operator} \keyword{new}} or \tcode{\keyword{operator} \keyword{new}[]} implicitly creates objects in the returned region of storage and returns a pointer to a suitable created object. @@ -3448,16 +3546,115 @@ \end{note} \indextext{object model|)} +\rSec2[basic.align]{Alignment} + +\pnum +Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}\iref{basic.fundamental,basic.compound} +which place restrictions on the addresses at which an object of that type +may be allocated. An \defn{alignment} is an \impldef{alignment} +integer value representing the number of bytes between successive addresses +at which a given object can be allocated. An object type imposes an alignment +requirement on every object of that type; stricter alignment can be requested +using the alignment specifier\iref{dcl.align}. +Attempting to create an object\iref{intro.object} in storage that +does not meet the alignment requirements of the object's type +is undefined behavior. + +\pnum +A \defnadj{fundamental}{alignment} is represented by an alignment +less than or equal to the greatest alignment supported by the implementation in +all contexts, which is equal to +\tcode{\keyword{alignof}(std::max_align_t)}\iref{support.types}. +The alignment required for a type may be different when it is used as the type +of a complete object and when it is used as the type of a subobject. +\begin{example} +\begin{codeblock} +struct B { long double d; }; +struct D : virtual B { char c; }; +\end{codeblock} + +When \tcode{D} is the type of a complete object, it will have a subobject of +type \tcode{B}, so it must be aligned appropriately for a \tcode{\keyword{long} \keyword{double}}. +If \tcode{D} appears as a subobject of another object that also has \tcode{B} +as a virtual base class, the \tcode{B} subobject might be part of a different +subobject, reducing the alignment requirements on the \tcode{D} subobject. +\end{example} +The result of the \keyword{alignof} operator reflects the alignment +requirement of the type in the complete-object case. + +\pnum +An \defnadj{extended}{alignment} is represented by an alignment +greater than \tcode{\keyword{alignof}(std::max_align_t)}. It is \impldef{support for extended alignments} +whether any extended alignments are supported and the contexts in which they are +supported\iref{dcl.align}. A type having an extended alignment +requirement is an \defnadj{over-aligned}{type}. +\begin{note} +Every over-aligned type is or contains a class type +to which extended alignment applies (possibly through a non-static data member). +\end{note} +A \defnadj{new-extended}{alignment} is represented by +an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. + +\pnum +Alignments are represented as values of the type \tcode{std::size_t}. +Valid alignments include only those values returned by an \keyword{alignof} +expression for the fundamental types plus an additional \impldef{alignment additional +values} +set of values, which may be empty. +Every alignment value shall be a non-negative integral power of two. + +\pnum +Alignments have an order from \defnx{weaker}{alignment!weaker} to +\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter +alignments have larger alignment values. An address that satisfies an alignment +requirement also satisfies any weaker valid alignment requirement. + +\pnum +The alignment requirement of a complete type can be queried using an +\keyword{alignof} expression\iref{expr.alignof}. Furthermore, +the narrow character types\iref{basic.fundamental} shall have the weakest +alignment requirement. +\begin{note} +This enables the ordinary character types to be used as the +underlying type for an aligned memory area\iref{dcl.align}. +\end{note} + +\pnum +Comparing alignments is meaningful and provides the obvious results: + +\begin{itemize} +\item Two alignments are equal when their numeric values are equal. +\item Two alignments are different when their numeric values are not equal. +\item When an alignment is larger than another it represents a stricter alignment. +\end{itemize} + +\pnum +\begin{note} +The runtime pointer alignment function\iref{ptr.align} +can be used to obtain an aligned pointer within a buffer; +an \grammarterm{alignment-specifier}\iref{dcl.align} +can be used to align storage explicitly. +\end{note} + +\pnum +If a request for a specific extended alignment in a specific context is not +supported by an implementation, the program is ill-formed. + \rSec2[basic.life]{Lifetime} +\pnum +In this subclause, ``before'' and ``after'' refer to the ``happens before'' +relation\iref{intro.multithread}. + \pnum \indextext{object lifetime|(}% The \defn{lifetime} of an object or reference is a runtime property of the object or reference. A variable is said to have \defnadj{vacuous}{initialization} -if it is default-initialized and, +if it is default-initialized, no other initialization is performed, and, if it is of class type or a (possibly multidimensional) array thereof, -that class type has a trivial default constructor. +a trivial constructor of that class type is selected for +the default-initialization. The lifetime of an object of type \tcode{T} begins when: \begin{itemize} \item storage with the proper alignment and size @@ -3551,7 +3748,7 @@ if the pointer were of type \tcode{\keyword{void}*} is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The -program has undefined behavior if: +program has undefined behavior if \begin{itemize} \item the pointer is used as the operand of a \grammarterm{delete-expression}, @@ -3614,7 +3811,7 @@ a glvalue refers to allocated storage\iref{basic.stc.dynamic.allocation}, and using the properties of the glvalue that do not depend on its value is -well-defined. The program has undefined behavior if: +well-defined. The program has undefined behavior if \begin{itemize} \item the glvalue is used to access the object, or \item the glvalue is used to call a non-static member function of the object, or @@ -3624,8 +3821,14 @@ \keyword{typeid}. \end{itemize} +\begin{note} +Therefore, undefined behavior results +if an object that is being constructed in one thread is referenced from another +thread without adequate synchronization. +\end{note} + \pnum -An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if: +An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if \begin{itemize} \item the storage that $o_2$ occupies exactly overlays the storage that $o_1$ occupied, and @@ -3734,22 +3937,11 @@ } \end{codeblock} \end{example} - -\pnum -In this subclause, ``before'' and ``after'' refer to the ``happens before'' -relation\iref{intro.multithread}. -\begin{note} -Therefore, undefined behavior results -if an object that is being constructed in one thread is referenced from another -thread without adequate synchronization. -\end{note} \indextext{object lifetime|)} \rSec2[basic.indet]{Indeterminate and erroneous values} \pnum -\indextext{value!indeterminate}% -\indextext{indeterminate value}% When storage for an object with automatic or dynamic storage duration is obtained, the bytes comprising the storage for the object @@ -3762,13 +3954,13 @@ the \tcode{[[indeterminate]]} attribute\iref{dcl.attr.indet}, the bytes have \defnadjx{indeterminate}{values}{value}; \item -otherwise, the bytes have erroneous values, +otherwise, the bytes have \defnadjx{erroneous}{values}{value}, where each value is determined by the implementation independently of the state of the program. \end{itemize} If no initialization is performed for an object (including subobjects), such a byte retains its initial value -until that value is replaced\iref{dcl.init.general,expr.ass}. +until that value is replaced\iref{dcl.init.general,expr.assign}. If any bit in the value representation has an indeterminate value, the object has an indeterminate value; otherwise, if any bit in the value representation has an erroneous value, @@ -3805,12 +3997,12 @@ a discarded-value expression\iref{expr.context}, \end{itemize} then the result of the operation is an indeterminate value or - that errorneous value, respectively. + that erroneous value, respectively. \item If an indeterminate or erroneous value of unsigned ordinary character type or \tcode{std::byte} type is produced by the evaluation of - the right operand of a simple assignment operator\iref{expr.ass} + the right operand of a simple assignment operator\iref{expr.assign} whose first operand is an lvalue of unsigned ordinary character type or \tcode{std::byte} type, an indeterminate value or that erroneous value, respectively, replaces @@ -3907,6 +4099,12 @@ \pnum The storage duration categories apply to references as well. +\pnum +\indextext{storage duration!class member}% +The storage duration of subobjects and reference members +is that of their complete object\iref{intro.object}. +\indextext{storage duration|)}% + \rSec3[basic.stc.static]{Static storage duration} \pnum @@ -4008,27 +4206,22 @@ \pnum The library provides default definitions for the global allocation and deallocation functions. Some global allocation and deallocation -functions are replaceable\iref{new.delete}; -these are attached to the global module\iref{module.unit}. -A \Cpp{} program shall -provide at most one definition of a replaceable allocation or -deallocation function. Any such function definition replaces the default -version provided in the library\iref{replacement.functions}. The -following allocation and deallocation functions\iref{support.dynamic} +functions are replaceable\iref{dcl.fct.def.replace}. +The following allocation and deallocation functions\iref{support.dynamic} are implicitly declared in global scope in each translation unit of a program. \begin{codeblock} -[[nodiscard]] void* operator new(std::size_t); -[[nodiscard]] void* operator new(std::size_t, std::align_val_t); +void* operator new(std::size_t); +void* operator new(std::size_t, std::align_val_t); void operator delete(void*) noexcept; void operator delete(void*, std::size_t) noexcept; void operator delete(void*, std::align_val_t) noexcept; void operator delete(void*, std::size_t, std::align_val_t) noexcept; -[[nodiscard]] void* operator new[](std::size_t); -[[nodiscard]] void* operator new[](std::size_t, std::align_val_t); +void* operator new[](std::size_t); +void* operator new[](std::size_t, std::align_val_t); void operator delete[](void*) noexcept; void operator delete[](void*, std::size_t) noexcept; @@ -4165,11 +4358,13 @@ functions in the \Cpp{} standard library. \begin{note} In particular, a -global allocation function is not called to allocate storage for objects -with static storage duration\iref{basic.stc.static}, for objects or references -with thread storage duration\iref{basic.stc.thread}, for objects of -type \tcode{std::type_info}\iref{expr.typeid}, or for an -exception object\iref{except.throw}. +global allocation function is not called to allocate storage +for objects with static storage duration\iref{basic.stc.static}, +for objects or references with thread storage duration\iref{basic.stc.thread}, +for objects of type \tcode{std::type_info}\iref{expr.typeid}, +for an object of type \tcode{std::contracts::contract_violation} +when a contract violation occurs\iref{basic.contract.eval}, or +for an exception object\iref{except.throw}. \end{note} \rSec4[basic.stc.dynamic.deallocation]{Deallocation functions} @@ -4239,134 +4434,32 @@ deallocation function shall deallocate the storage referenced by the pointer, ending the duration of the region of storage. -\rSec3[basic.stc.inherit]{Duration of subobjects} +\rSec2[class.temporary]{Temporary objects} \pnum -\indextext{storage duration!class member}% -The storage duration of subobjects and reference members -is that of their complete object\iref{intro.object}. -\indextext{storage duration|)}% - -\rSec2[basic.align]{Alignment} - -\pnum -Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}\iref{basic.fundamental,basic.compound} -which place restrictions on the addresses at which an object of that type -may be allocated. An \defn{alignment} is an \impldef{alignment} -integer value representing the number of bytes between successive addresses -at which a given object can be allocated. An object type imposes an alignment -requirement on every object of that type; stricter alignment can be requested -using the alignment specifier\iref{dcl.align}. -Attempting to create an object\iref{intro.object} in storage that -does not meet the alignment requirements of the object's type -is undefined behavior. - -\pnum -A \defnadj{fundamental}{alignment} is represented by an alignment -less than or equal to the greatest alignment supported by the implementation in -all contexts, which is equal to -\tcode{\keyword{alignof}(std::max_align_t)}\iref{support.types}. -The alignment required for a type may be different when it is used as the type -of a complete object and when it is used as the type of a subobject. -\begin{example} -\begin{codeblock} -struct B { long double d; }; -struct D : virtual B { char c; }; -\end{codeblock} - -When \tcode{D} is the type of a complete object, it will have a subobject of -type \tcode{B}, so it must be aligned appropriately for a \tcode{\keyword{long} \keyword{double}}. -If \tcode{D} appears as a subobject of another object that also has \tcode{B} -as a virtual base class, the \tcode{B} subobject might be part of a different -subobject, reducing the alignment requirements on the \tcode{D} subobject. -\end{example} -The result of the \keyword{alignof} operator reflects the alignment -requirement of the type in the complete-object case. - -\pnum -An \defnadj{extended}{alignment} is represented by an alignment -greater than \tcode{\keyword{alignof}(std::max_align_t)}. It is \impldef{support for extended alignments} -whether any extended alignments are supported and the contexts in which they are -supported\iref{dcl.align}. A type having an extended alignment -requirement is an \defnadj{over-aligned}{type}. -\begin{note} -Every over-aligned type is or contains a class type -to which extended alignment applies (possibly through a non-static data member). -\end{note} -A \defnadj{new-extended}{alignment} is represented by -an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. - -\pnum -Alignments are represented as values of the type \tcode{std::size_t}. -Valid alignments include only those values returned by an \keyword{alignof} -expression for the fundamental types plus an additional \impldef{alignment additional -values} -set of values, which may be empty. -Every alignment value shall be a non-negative integral power of two. - -\pnum -Alignments have an order from \defnx{weaker}{alignment!weaker} to -\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter -alignments have larger alignment values. An address that satisfies an alignment -requirement also satisfies any weaker valid alignment requirement. - -\pnum -The alignment requirement of a complete type can be queried using an -\keyword{alignof} expression\iref{expr.alignof}. Furthermore, -the narrow character types\iref{basic.fundamental} shall have the weakest -alignment requirement. -\begin{note} -This enables the ordinary character types to be used as the -underlying type for an aligned memory area\iref{dcl.align}. -\end{note} - -\pnum -Comparing alignments is meaningful and provides the obvious results: - -\begin{itemize} -\item Two alignments are equal when their numeric values are equal. -\item Two alignments are different when their numeric values are not equal. -\item When an alignment is larger than another it represents a stricter alignment. -\end{itemize} - -\pnum -\begin{note} -The runtime pointer alignment function\iref{ptr.align} -can be used to obtain an aligned pointer within a buffer; -an \grammarterm{alignment-specifier}\iref{dcl.align} -can be used to align storage explicitly. -\end{note} - -\pnum -If a request for a specific extended alignment in a specific context is not -supported by an implementation, the program is ill-formed. - -\rSec2[class.temporary]{Temporary objects} - -\pnum -\indextext{object temporary|see{temporary}}% -\indextext{temporary}% -\indextext{optimization of temporary|see{temporary, elimination of}}% -\indextext{temporary!elimination of}% -\indextext{temporary!implementation-defined generation of}% -Temporary objects are created -\begin{itemize} -\item -when a prvalue is converted to an xvalue\iref{conv.rval} and -\item -when needed by the implementation to pass or return an object of trivially copyable type (see below). -\end{itemize} -Even when the creation of the temporary object is -unevaluated\iref{expr.context}, -all the semantic restrictions shall be respected as if the temporary object -had been created and later destroyed. -\begin{note} -This includes accessibility\iref{class.access} and whether it is deleted, -for the constructor selected and for the destructor. However, in the special -case of the operand of a -\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, no temporary is introduced, -so the foregoing does not apply to such a prvalue. -\end{note} +\indextext{object temporary|see{temporary}}% +\indextext{temporary}% +\indextext{optimization of temporary|see{temporary, elimination of}}% +\indextext{temporary!elimination of}% +\indextext{temporary!implementation-defined generation of}% +Temporary objects are created +\begin{itemize} +\item +when a prvalue is converted to an xvalue\iref{conv.rval} and +\item +when needed by the implementation to pass or return an object of suitable type (see below). +\end{itemize} +Even when the creation of the temporary object is +unevaluated\iref{expr.context}, +all the semantic restrictions shall be respected as if the temporary object +had been created and later destroyed. +\begin{note} +This includes accessibility\iref{class.access} and whether it is deleted, +for the constructor selected and for the destructor. However, in the special +case of the operand of a +\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, no temporary is introduced, +so the foregoing does not apply to such a prvalue. +\end{note} \pnum The materialization of a temporary object is generally @@ -4438,34 +4531,49 @@ \pnum When an object of class type \tcode{X} -is passed to or returned from a function, -if \tcode{X} has at least one eligible copy or move constructor\iref{special}, -each such constructor is trivial, +is passed to or returned from a potentially-evaluated function call, +if \tcode{X} is +\begin{itemize} +\item +a scalar type or +\item +a class type that +has at least one eligible copy or move constructor\iref{special}, +where each such constructor is trivial, and the destructor of \tcode{X} is either trivial or deleted, +\end{itemize} implementations are permitted -to create a temporary object -to hold the function parameter or result object. -The temporary object is constructed -from the function argument or return value, respectively, -and the function's parameter or return object -is initialized as if by -using the eligible trivial constructor to copy the temporary -(even if that constructor is inaccessible +to create temporary objects +to hold the function parameter or result object, +as follows: +\begin{itemize} +\item +The first such temporary object +is constructed from the function argument or return value, respectively. +\item +Each successive temporary object +is initialized from the previous one +as if by direct-initialization if \tcode{X} is a scalar type, +otherwise by using an eligible trivial constructor. +\item +The function parameter or return object is initialized +from the final temporary +as if by direct-initialization if \tcode{X} is a scalar type, +otherwise by using an eligible trivial constructor. +\end{itemize} +(In all cases, the eligible constructor is used +even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object). \begin{note} -This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. +This latitude is granted to allow objects +to be passed to or returned from functions in registers. \end{note} \pnum \indextext{temporary!constructor for}% \indextext{temporary!destructor for}% \indextext{temporary!destruction of}% -When an implementation introduces a temporary object of a class that has a -non-trivial constructor\iref{class.default.ctor,class.copy.ctor}, -it shall ensure that a constructor is called for the temporary object. -Similarly, the destructor shall be called for a temporary with a non-trivial -destructor\iref{class.dtor}. Temporary objects are destroyed as the last step in evaluating the full-expression\iref{intro.execution} @@ -4483,7 +4591,7 @@ \pnum \indextext{initializer!temporary and declarator}% \indextext{temporary!order of destruction of}% -There are four contexts in which temporaries are destroyed at a different +There are five contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer\iref{dcl.init}. @@ -4609,6 +4717,14 @@ the object persists for the lifetime of the reference initialized by the \grammarterm{for-range-initializer}. +\pnum +The fifth context is when a temporary object +is created in a structured binding declaration\iref{dcl.struct.bind}. +Any temporary objects introduced by +the \grammarterm{initializer}{s} for the variables +with unique names +are destroyed at the end of the structured binding declaration. + \pnum Let \tcode{x} and \tcode{y} each be either a temporary object whose lifetime is not extended, or @@ -4915,11 +5031,14 @@ Scalar types, trivially copyable class types\iref{class.prop}, arrays of such types, and cv-qualified versions of these types are collectively called \defnadjx{trivially copyable}{types}{type}. -\label{term.trivial.type}% -Scalar types, trivial class types\iref{class.prop}, +\label{term.trivially.relocatable.type}% +Scalar types, trivially relocatable class types\iref{class.prop}, arrays of such types, and cv-qualified versions of these -types are collectively called -\defnadjx{trivial}{types}{type}. +types are collectively called \defnadjx{trivially relocatable}{types}{type}. +\label{term.replaceable.type}% +Cv-unqualified scalar types, replaceable class types\iref{class.prop}, and +arrays of such types are collectively called +\defnadjx{replaceable}{types}{type}. \label{term.standard.layout.type}% Scalar types, standard-layout class types\iref{class.prop}, arrays of such types, and @@ -4942,7 +5061,7 @@ has all of the following properties: \begin{itemize} \item it has a constexpr destructor\iref{dcl.constexpr}, -\item all of its non-static non-variant data members and base classes are of non-volatile literal types, and +\item all of its non-variant non-static data members and base classes are of non-volatile literal types, and \item it \begin{itemize} \item is a closure type\iref{expr.prim.lambda.closure}, @@ -5051,7 +5170,7 @@ the largest value of the corresponding unsigned type. \end{example} -\begin{floattable}{Minimum width}{basic.fundamental.width}{ll} +\begin{floattable}{Minimum width}{basic.fundamental.width}{lc} \topline \lhdr{Type} & \rhdr{Minimum width $N$} \\ \capsep @@ -5072,11 +5191,11 @@ alternative representations of the value specified by the value representation. \begin{note} Padding bits have unspecified value, but cannot cause traps. -In contrast, see ISO C 6.2.6.2. +In contrast, see \IsoC{} 6.2.6.2. \end{note} \begin{note} The signed and unsigned integer types satisfy -the constraints given in ISO C 5.2.4.2.1. +the constraints given in \IsoC{} 5.2.4.2.1. \end{note} Except as specified above, the width of a signed or unsigned integer type is @@ -5236,9 +5355,9 @@ the range of that type is extended to all positive real numbers. \begin{note} Since negative and positive infinity are representable -in ISO/IEC/IEEE 60559 formats, +in \IsoFloatUndated{} formats, all real numbers lie within the range of representable values of -a floating-point type adhering to ISO/IEC/IEEE 60559. +a floating-point type adhering to \IsoFloatUndated{}. \end{note} \pnum @@ -5258,21 +5377,25 @@ A type \cv{}~\keyword{void} is an incomplete type that cannot be completed; such a type has an empty set of values. It is used as the return -type for functions that do not return a value. Any expression can be -explicitly converted to type -\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. +type for functions that do not return a value. An expression of type \cv{}~\keyword{void} shall -be used only as an expression statement\iref{stmt.expr}, as an operand -of a comma expression\iref{expr.comma}, as a second or third operand -of \tcode{?:}\iref{expr.cond}, as the operand of -\keyword{typeid}, \keyword{noexcept}, or \keyword{decltype}, as -the expression in a \keyword{return} statement\iref{stmt.return} for a function -with the return type \cv{}~\keyword{void}, or as the operand of an explicit conversion -to type \cv{}~\keyword{void}. +be used only as +\begin{itemize} +\item an expression statement\iref{stmt.expr}, +\item the expression in a \keyword{return} statement\iref{stmt.return} +for a function with the return type \cv{}~\keyword{void}, +\item an operand of a comma expression\iref{expr.comma}, +\item the second or third operand of \tcode{?:}\iref{expr.cond}, +\item the operand of a \keyword{typeid} expression\iref{expr.typeid}, +\item the operand of a \keyword{noexcept} operator\iref{expr.unary.noexcept}, +\item the operand of a \keyword{decltype} specifier\iref{dcl.type.decltype}, or +\item the operand of an explicit conversion to type +\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. +\end{itemize} \pnum The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. -A value of type \tcode{std::nullptr_t} is a null pointer +A prvalue of type \tcode{std::nullptr_t} is a null pointer constant\iref{conv.ptr}. Such values participate in the pointer and the pointer-to-member conversions\iref{conv.ptr,conv.mem}. \tcode{\keyword{sizeof}(std::nullptr_t)} shall be equal to \tcode{\keyword{sizeof}(\keyword{void}*)}. @@ -5291,9 +5414,9 @@ \pnum If the implementation supports an extended floating-point type\iref{basic.fundamental} whose properties are specified by -the ISO/IEC/IEEE 60559 floating-point interchange format binary16, +the \IsoFloatUndated{} floating-point interchange format binary16, then the \grammarterm{typedef-name} \tcode{std::float16_t} -is defined in the header \libheaderref{stdfloat} and names such a type, +is declared in the header \libheaderref{stdfloat} and names such a type, the macro \mname{STDCPP_FLOAT16_T} is defined\iref{cpp.predefined}, and the floating-point literal suffixes \tcode{f16} and \tcode{F16} are supported\iref{lex.fcon}. @@ -5301,40 +5424,40 @@ \pnum If the implementation supports an extended floating-point type whose properties are specified by -the ISO/IEC/IEEE 60559 floating-point interchange format binary32, +the \IsoFloatUndated{} floating-point interchange format binary32, then the \grammarterm{typedef-name} \tcode{std::float32_t} -is defined in the header \libheader{stdfloat} and names such a type, +is declared in the header \libheader{stdfloat} and names such a type, the macro \mname{STDCPP_FLOAT32_T} is defined, and the floating-point literal suffixes \tcode{f32} and \tcode{F32} are supported. \pnum If the implementation supports an extended floating-point type whose properties are specified by -the ISO/IEC/IEEE 60559 floating-point interchange format binary64, +the \IsoFloatUndated{} floating-point interchange format binary64, then the \grammarterm{typedef-name} \tcode{std::float64_t} -is defined in the header \libheader{stdfloat} and names such a type, +is declared in the header \libheader{stdfloat} and names such a type, the macro \mname{STDCPP_FLOAT64_T} is defined, and the floating-point literal suffixes \tcode{f64} and \tcode{F64} are supported. \pnum If the implementation supports an extended floating-point type whose properties are specified by -the ISO/IEC/IEEE 60559 floating-point interchange format binary128, +the \IsoFloatUndated{} floating-point interchange format binary128, then the \grammarterm{typedef-name} \tcode{std::float128_t} -is defined in the header \libheader{stdfloat} and names such a type, +is declared in the header \libheader{stdfloat} and names such a type, the macro \mname{STDCPP_FLOAT128_T} is defined, and the floating-point literal suffixes \tcode{f128} and \tcode{F128} are supported. \pnum If the implementation supports an extended floating-point type -with the properties, as specified by ISO/IEC/IEEE 60559, of +with the properties, as specified by \IsoFloatUndated{}, of radix ($b$) of 2, storage width in bits ($k$) of 16, precision in bits ($p$) of 8, maximum exponent ($emax$) of 127, and exponent field width in bits ($w$) of 8, then the \grammarterm{typedef-name} \tcode{std::bfloat16_t} -is defined in the header \libheader{stdfloat} and names such a type, +is declared in the header \libheader{stdfloat} and names such a type, the macro \mname{STDCPP_BFLOAT16_T} is defined, and the floating-point literal suffixes \tcode{bf16} and \tcode{BF16} are supported. @@ -5343,7 +5466,7 @@ A summary of the parameters for each type is given in \tref{basic.extended.fp}. The precision $p$ includes the implicit 1 bit at the beginning of the significand, so the storage used for the significand is $p-1$ bits. -ISO/IEC/IEEE 60559 does not assign a name for a type +\IsoFloatUndated{} does not assign a name for a type having the parameters specified for \tcode{std::bfloat16_t}. \end{note} \begin{floattable} @@ -5353,7 +5476,7 @@ \chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & \rhdr{\tcode{bfloat16_t}} \\ \capsep -ISO/IEC/IEEE 60559 name & binary16 & binary32 & binary64 & binary128 & \\ +\IsoFloatUndated{} name & binary16 & binary32 & binary64 & binary128 & \\ $k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ $p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ $emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ @@ -5364,7 +5487,7 @@ \recommended Any names that the implementation provides for the extended floating-point types described in this subsection -that are in addition to the names defined in the \libheader{stdfloat} header +that are in addition to the names declared in the \libheader{stdfloat} header should be chosen to increase compatibility and interoperability with the interchange types \tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} @@ -5379,7 +5502,7 @@ \item \defnx{arrays}{type!array} of objects of a given type, \ref{dcl.array}; \item \defnx{functions}{type!function}, which have parameters of given types and return -\keyword{void} or references or objects of a given type, \ref{dcl.fct}; +\keyword{void} or a result of a given type, \ref{dcl.fct}; \item \defnx{pointers}{type!pointer} to \cv{}~\keyword{void} or objects or functions (including static members of classes) of a given type, \ref{dcl.ptr}; @@ -5395,9 +5518,8 @@ \end{itemize} \item -\defnx{classes}{class} containing a sequence of objects of various types\iref{class}, -a set of types, enumerations and functions for -manipulating these objects\iref{class.mfct}, and a set of restrictions +\defnx{classes}{class} containing a sequence of class members\iref{class,class.mem}, +and a set of restrictions on the access to these entities\iref{class.access}; \item @@ -5487,7 +5609,7 @@ a pointer past the end of the last element of an array \tcode{x} of $n$ elements is considered to be equivalent to -a pointer to a hypothetical array element $n$ of \tcode{x} and +a pointer to a hypothetical array element $n$ of \tcode{x}, and an object of type \tcode{T} that is not an array element is considered to belong to an array with one element of type \tcode{T}. The value representation of @@ -5505,7 +5627,7 @@ A pointer value $P$ is \indextext{value!valid in the context of an evaluation}% \defn{valid in the context of} an evaluation $E$ -if $P$ is a null pointer value, or +if $P$ is a pointer to function or a null pointer value, or if it is a pointer to or past the end of an object $O$ and $E$ happens before the end of the duration of the region of storage for $O$. If a pointer value $P$ is used in an evaluation $E$ and @@ -5527,7 +5649,7 @@ \end{note} \pnum -Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if: +Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if \begin{itemize} \item they are the same object, or @@ -5767,6 +5889,15 @@ An extended floating-point type with the same set of values as more than one cv-unqualified standard floating-point type has a rank equal to the rank of \keyword{double}. +\begin{tailnote} +The treatment of \tcode{std::float64_t} differs from +that of the analogous \tcode{_Float64} in C, +for example on platforms where all of +\tcode{\keyword{long} \keyword{double}}, +\keyword{double}, and +\tcode{std::float64_t} +have the same set of values (see \IsoCUndated{}:2024 H.4.2). +\end{tailnote} \end{itemize} \begin{note} The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} @@ -5885,13 +6016,16 @@ \item an immediate invocation\iref{expr.const}, \item -an \grammarterm{init-declarator}\iref{dcl.decl} or +an \grammarterm{init-declarator}\iref{dcl.decl} +(including such introduced by a structured binding\iref{dcl.struct.bind}) or a \grammarterm{mem-initializer}\iref{class.base.init}, including the constituent expressions of the initializer, \item an invocation of a destructor generated at the end of the lifetime of an object other than a temporary object\iref{class.temporary} -whose lifetime has not been extended, or +whose lifetime has not been extended, +\item +the predicate of a contract assertion\iref{basic.contract}, or \item an expression that is not a subexpression of another expression and that is not otherwise part of a full-expression. @@ -6017,13 +6151,30 @@ \end{note} The value computations of the operands of an operator are sequenced before the value computation of the result of the -operator. If a +operator. +The behavior is undefined if +\begin{itemize} +\item \indextext{side effects}% -side effect on a memory location\iref{intro.memory} is unsequenced -relative to either another side effect on the same memory location or +a side effect on a memory location\iref{intro.memory} or +\item +starting or ending the lifetime of an object in a memory location +\end{itemize} +is unsequenced relative to +\begin{itemize} +\item +another side effect on the same memory location, +\item +starting or ending the lifetime of an object occupying storage that +overlaps with the memory location, or +\item a value computation using the value of any object in the same memory location, -and they are not potentially concurrent\iref{intro.multithread}, -the behavior is undefined. +\end{itemize} +and the two evaluations are not potentially concurrent\iref{intro.multithread}. +\begin{note} +Starting the lifetime of an object in a memory location can end the lifetime of +objects in other memory locations\iref{basic.life}. +\end{note} \begin{note} The next subclause imposes similar, but more complex restrictions on potentially concurrent computations. @@ -6037,20 +6188,35 @@ i = i++ + 1; // the value of \tcode{i} is incremented i = i++ + i; // undefined behavior i = i + 1; // the value of \tcode{i} is incremented + + union U { int x, y; } u; + (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior } \end{codeblock} \end{example} \pnum -When invoking a function (whether or not the function is inline), +When invoking a function \placeholder{f} (whether or not the function is inline), every argument expression and -the postfix expression designating the called function -are sequenced before every expression or statement -in the body of the called function. -For each function invocation or -evaluation of an \grammarterm{await-expression} \placeholder{F}, -each evaluation that does not occur within \placeholder{F} but -is evaluated on the same thread and as part of the same signal handler (if any) +the postfix expression designating \placeholder{f} +are sequenced before +every precondition assertion of \placeholder{f}\iref{dcl.contract.func}, +which in turn are sequenced before +every expression or statement +in the body of \placeholder{f}, +which in turn are sequenced before +every postcondition assertion of \placeholder{f}. + +\pnum +For each +\begin{itemize} +\item function invocation, +\item evaluation of an \grammarterm{await-expression}\iref{expr.await}, or +\item evaluation of a \grammarterm{throw-expression}\iref{expr.throw} +\end{itemize} +\placeholder{F}, +each evaluation that does not occur within \placeholder{F} +but is evaluated on the same thread and as part of the same signal handler (if any) is either sequenced before all evaluations that occur within \placeholder{F} or sequenced after all evaluations that occur within \placeholder{F}; \begin{footnote} @@ -6063,6 +6229,7 @@ prior to the next suspension (if any) are considered to occur within \placeholder{F}. +\pnum Several contexts in \Cpp{} cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. @@ -6072,6 +6239,8 @@ invocation of a conversion function\iref{class.conv.fct} can arise in contexts in which no function call syntax appears. \end{example} + +\pnum The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, regardless of the syntax of the expression that calls the function.% @@ -6147,16 +6316,32 @@ \end{note} \pnum -Two expression evaluations \defn{conflict} if one of them modifies a memory -location\iref{intro.memory} and the other one reads or modifies the same -memory location. +Two expression evaluations \defn{conflict} if one of them +\begin{itemize} +\item +modifies\iref{defns.access} a memory location\iref{intro.memory} or +\item +starts or ends the lifetime of an object in a memory location +\end{itemize} +and the other one +\begin{itemize} +\item +reads or modifies the same memory location or +\item +starts or ends the lifetime of an object occupying storage that +overlaps with the memory location. +\end{itemize} +\begin{note} +A modification can still conflict +even if it does not alter the value of any bits. +\end{note} \pnum The library defines a number of atomic operations\iref{atomics} and operations on mutexes\iref{thread} that are specially identified as synchronization operations. These operations play a special role in making assignments in one thread visible to another. A synchronization operation on one -or more memory locations is either a consume operation, an acquire operation, a +or more memory locations is either an acquire operation, a release operation, or both an acquire and release operation. A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence. In @@ -6212,122 +6397,17 @@ the value written'' by the last mutex release. \end{note} -\pnum -An evaluation $A$ \defn{carries a dependency} to an evaluation $B$ if -\begin{itemize} -\item -the value of $A$ is used as an operand of $B$, unless: -\begin{itemize} -\item -$B$ is an invocation of any specialization of -\tcode{std::kill_dependency}\iref{atomics.order}, or -\item -$A$ is the left operand of a built-in logical \logop{and} (\tcode{\&\&}, -see~\ref{expr.log.and}) or logical \logop{or} (\tcode{||}, see~\ref{expr.log.or}) -operator, or -\item -$A$ is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) -operator, or -\item -$A$ is the left operand of the built-in comma (\tcode{,}) -operator\iref{expr.comma}; \end{itemize} or -\item -$A$ writes a scalar object or bit-field $M$, $B$ reads the value -written by $A$ from $M$, and $A$ is sequenced before $B$, or -\item -for some evaluation $X$, $A$ carries a dependency to $X$, and -$X$ carries a dependency to $B$. -\end{itemize} -\begin{note} -``Carries a dependency to'' is a subset of ``is sequenced before'', -and is similarly strictly intra-thread. -\end{note} - -\pnum -An evaluation $A$ is \defn{dependency-ordered before} an evaluation -$B$ if -\begin{itemize} -\item -$A$ performs a release operation on an atomic object $M$, and, in -another thread, $B$ performs a consume operation on $M$ and reads -the value written by $A$, or - -\item -for some evaluation $X$, $A$ is dependency-ordered before $X$ and -$X$ carries a dependency to $B$. - -\end{itemize} -\begin{note} -The relation ``is dependency-ordered before'' is analogous to -``synchronizes with'', but uses release/consume in place of release/acquire. -\end{note} - -\pnum -An evaluation $A$ \defn{inter-thread happens before} an evaluation $B$ -if -\begin{itemize} -\item - $A$ synchronizes with $B$, or -\item - $A$ is dependency-ordered before $B$, or -\item - for some evaluation $X$ - \begin{itemize} - \item - $A$ synchronizes with $X$ and $X$ - is sequenced before $B$, or - \item - $A$ is sequenced before $X$ and $X$ - inter-thread happens before $B$, or - \item - $A$ inter-thread happens before $X$ and $X$ - inter-thread happens before $B$. - \end{itemize} -\end{itemize} -\begin{note} -The ``inter-thread happens before'' relation describes arbitrary -concatenations of ``sequenced before'', ``synchronizes with'' and -``dependency-ordered before'' relationships, with two exceptions. The first -exception is that a concatenation never ends with -``dependency-ordered before'' followed by ``sequenced before''. The reason for -this limitation is that a consume operation participating in a -``dependency-ordered before'' relationship provides ordering only with respect -to operations to which this consume operation actually carries a dependency. The -reason that this limitation applies only to the end of such a concatenation is -that any subsequent release operation will provide the required ordering for a -prior consume operation. The second exception is that a concatenation never -consist entirely of ``sequenced before''. The reasons for this -limitation are (1) to permit ``inter-thread happens before'' to be transitively -closed and (2) the ``happens before'' relation, defined below, provides for -relationships consisting entirely of ``sequenced before''. -\end{note} - \pnum An evaluation $A$ \defn{happens before} an evaluation $B$ -(or, equivalently, $B$ \defn{happens after} $A$) if: -\begin{itemize} -\item $A$ is sequenced before $B$, or -\item $A$ inter-thread happens before $B$. -\end{itemize} -The implementation shall ensure that no program execution demonstrates a cycle -in the ``happens before'' relation. -\begin{note} -This cycle would otherwise be -possible only through the use of consume operations. -\end{note} - -\pnum -An evaluation $A$ \defn{simply happens before} an evaluation $B$ +(or, equivalently, $B$ happens after $A$) if either \begin{itemize} \item $A$ is sequenced before $B$, or \item $A$ synchronizes with $B$, or -\item $A$ simply happens before $X$ and -$X$ simply happens before $B$. +\item $A$ happens before $X$ and $X$ happens before $B$. \end{itemize} \begin{note} -In the absence of consume operations, -the happens before and simply happens before relations are identical. +An evaluation does not happen before itself. \end{note} \pnum @@ -6340,7 +6420,7 @@ sequentially consistent atomic operations\iref{atomics.order}, or \item there are evaluations $B$ and $C$ such that $A$ is sequenced before $B$, -$B$ simply happens before $C$, and +$B$ happens before $C$, and $C$ is sequenced before $D$, or \item there is an evaluation $B$ such that $A$ strongly happens before $B$, and @@ -6349,7 +6429,7 @@ \begin{note} Informally, if $A$ strongly happens before $B$, then $A$ appears to be evaluated before $B$ -in all contexts. Strongly happens before excludes consume operations. +in all contexts. \end{note} \pnum @@ -6492,7 +6572,8 @@ \end{note} \pnum -Two accesses to the same object of type \tcode{\keyword{volatile} std::sig_atomic_t} do not +Two accesses to the same non-bit-field object +of type \tcode{\keyword{volatile} std::sig_atomic_t} do not result in a data race if both occur in the same thread, even if one or more occurs in a signal handler. For each signal handler invocation, evaluations performed by the thread invoking a signal handler can be divided into two @@ -6518,8 +6599,8 @@ \pnum \begin{note} -Transformations that introduce a speculative read of a potentially -shared memory location might not preserve the semantics of the \Cpp{} program as +It is possible that transformations that introduce a speculative read of a potentially +shared memory location do not preserve the semantics of the \Cpp{} program as defined in this document, since they potentially introduce a data race. However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races. They would be @@ -6786,7 +6867,7 @@ \tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial characters of null-terminated multibyte strings (\ntmbs{}s)\iref{multibyte.strings} and \tcode{argv[0]} shall be the pointer to -the initial character of a \ntmbs{} that represents the name used to +the initial character of an \ntmbs{} that represents the name used to invoke the program or \tcode{""}. The value of \tcode{argc} shall be non-negative. The value of \tcode{argv[argc]} shall be 0. @@ -6840,9 +6921,10 @@ \pnum \indextext{termination!program}% \indextext{\idxcode{main} function!return from}% -A \keyword{return} statement\iref{stmt.return} in \tcode{main} has the effect of leaving the main -function (destroying any objects with automatic storage duration) and -calling \tcode{std::exit} with the return value as the argument. +A \keyword{return} statement\iref{stmt.return} in \tcode{main} has the effect of leaving the \tcode{main} +function (destroying any objects with automatic storage duration +and evaluating any postcondition assertions of \tcode{main}) +and calling \tcode{std::exit} with the return value as the argument. If control flows off the end of the \grammarterm{compound-statement} of \tcode{main}, the effect is equivalent to a \keyword{return} with operand \tcode{0} @@ -6862,7 +6944,7 @@ \pnum \indextext{initialization!constant}% \defnx{Constant initialization}{constant initialization} is performed -if a variable or temporary object with static or thread storage duration +if a variable with static or thread storage duration is constant-initialized\iref{expr.const}. \indextext{initialization!zero-initialization}% If constant initialization is not performed, a variable with static @@ -7174,3 +7256,442 @@ the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% \indextext{program!termination|)} \indextext{program execution|)} + +\rSec1[basic.contract]{Contract assertions}% +\indextext{contract assertion|(}% + +\rSec2[basic.contract.general]{General}% + +\pnum +\defnx{Contract assertions}{contract assertion} +allow the programmer to specify +properties of the state of the program +that are expected to hold at +certain points during execution. +Contract assertions are introduced by +\grammarterm{precondition-specifier}s, +\grammarterm{postcondition-specifier}s\iref{dcl.contract.func}, and +\grammarterm{assertion-statement}s\iref{stmt.contract.assert}. + +\pnum +Each contract assertion has a \defnadjx{contract-assertion}{predicate}{predicate}, +which is an expression of type \tcode{bool}. + +\begin{note} +The value of the predicate is used to identify program states that are +expected. +\end{note} + +\pnum +An invocation of the macro \tcode{va_start}\iref{cstdarg.syn} +shall not be a subexpression +of the predicate of a contract assertion, +no diagnostic required. + +\pnum +\begin{note} +Within the predicate of a contract assertion, +\grammarterm{id-expression}s referring to +variables declared outside the contract assertion +are \keyword{const}\iref{expr.prim.id.unqual}, +\tcode{this} is a pointer to \keyword{const}\iref{expr.prim.this}, +and the result object can be named +if a \grammarterm{result-name-introducer}\iref{dcl.contract.res} has been specified. +\end{note} + +\rSec2[basic.contract.eval]{Evaluation} + +\pnum +\indexdefn{evaluation semantics|see{contract evaluation semantics}}% +\indexdefn{checking semantics|see{contract evaluation semantics!checking}}% +\indexdefn{terminating semantics|see{contract evaluation semantics!terminating}}% +An evaluation of a contract assertion +uses one of the following four \defn{evaluation semantics}: +\defnx{ignore}{contract evaluation semantics!ignore}, +\defnx{observe}{contract evaluation semantics!observe}, +\defnx{enforce}{contract evaluation semantics!enforce}, or +\defnx{quick-enforce}{contract evaluation semantics!quick-enforce}. +Observe, enforce, and quick-enforce are \defnx{checking semantics}{contract evaluation semantics!checking}; +enforce and quick-enforce are \defnx{terminating semantics}{contract evaluation semantics!terminating}. + +\pnum +It is +\impldef{evaluation semantic used for the evaluation of a contract assertion} +which evaluation semantic is used +for any given evaluation of a contract assertion. +\begin{note} +The range and flexibility of available choices of +evaluation semantics depends on the implementation +and need not allow all four evaluation semantics as possibilities. +The evaluation semantics can differ +for different evaluations of the same contract assertion, +including evaluations during constant evaluation. +\end{note} + +\pnum +\recommended +An implementation should provide +the option to translate a program +such that all evaluations of contract assertions use the ignore semantic +as well as +the option to translate a program +such that all evaluations of contract assertions use the enforce semantic. +By default, +evaluations of contract assertions should use the enforce semantic. + +\pnum +The evaluation of a contract assertion using the ignore semantic has no effect. +\begin{note} +The predicate is potentially evaluated\iref{basic.def.odr}, +but not evaluated. +\end{note} + +\pnum +The evaluation $A$ of a contract assertion +using a checking semantic +determines the value of the predicate. +It is unspecified +whether the predicate is evaluated. +Let $B$ be the value that would result from evaluating the predicate. +\begin{note} +To determine whether a predicate would evaluate +to \keyword{true} or \keyword{false}, +an alternative evaluation +that produces the same value as the predicate +but has no side effects +can occur. +\begin{example} +\begin{codeblock} +struct S { + mutable int g = 5; +} s; +void f() + pre(( s.g++, false )); // \#1 +void g() +{ + f(); // Increment of \tcode{s.g} might not occur, even if \#1 uses a checking semantic. +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +There is an observable checkpoint\iref{intro.abstract} $C$ +that happens before $A$ +such that any other operation $O$ +that happens before $A$ +also happens before $C$. + +\pnum +A \defn{contract violation} occurs when +\begin{itemize} +\item +$B$ is \keyword{false}, +\item +the evaluation of the predicate +exits via an exception, or +\item +the evaluation of the predicate +is performed in a context that is +manifestly constant-evaluated\iref{expr.const} +and the predicate +is not a core constant expression. +\end{itemize} + +\begin{note} +If $B$ is \keyword{true}, +no contract violation occurs and +control flow continues normally +after the point of evaluation of the contract assertion. +The evaluation of the predicate +can fail to produce a value +without causing a contract violation, +for example, +by calling \tcode{longjmp}\iref{csetjmp.syn} +or terminating the program. +\end{note} + +\pnum +\indexdefn{contract evaluation semantics!terminating}% +If a contract violation occurs +in a context that is manifestly constant-evaluated\iref{expr.const}, +and the evaluation semantic is +a terminating semantic, +the program is ill-formed. + +\begin{note} +A diagnostic is produced +if the evaluation semantic is observe\iref{intro.compliance}. +\end{note} + +\begin{note} +Different evaluation semantics +chosen for the same contract assertion +in different translation units +can result in +violations of the one-definition rule\iref{basic.def.odr} +when a contract assertion has side effects +that alter the value produced by a constant expression. +\begin{example} +\begin{codeblock} +constexpr int f(int i) +{ + contract_assert((++const_cast(i), true)); + return i; +} +inline void g() +{ + int a[f(1)]; // size dependent on the evaluation semantic of \tcode{contract_assert} above +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +When the program is \defn{contract-terminated}, +it is +\impldef{method by which contract termination occurs} +(depending on context) whether +\begin{itemize} +\item +\tcode{std::terminate} is called, +\item +\tcode{std::abort} is called, or +\item +execution is terminated. + +\begin{note} +No further execution steps occur\iref{intro.progress}. +\end{note} +\end{itemize} + +\begin{note} +Performing the actions of +\tcode{std::terminate} or \tcode{std::abort} +without actually making a library call +is a conforming implementation of +contract-termination\iref{intro.abstract}. +\end{note} + +\pnum +\indextext{contract evaluation semantics!enforce}% +\indextext{contract evaluation semantics!quick-enforce}% +If a contract violation occurs +in a context that is not manifestly constant-evaluated +and the evaluation semantic is quick-enforce, +the program is contract-terminated. + +\pnum +\indextext{\idxcode{contract_violation}}% +\indextext{contract evaluation semantics!enforce}% +\indextext{contract evaluation semantics!observe}% +\indexlibraryglobal{contract_violation}% +If a contract violation occurs +in a context that is not manifestly constant-evaluated +and the evaluation semantic is enforce or observe, +the contract-violation handler\iref{basic.contract.handler} +is invoked with an lvalue referring to +an object \tcode{v} +of type \tcode{const std::contracts::contract_violation}\iref{support.contract.violation} +containing information about the contract violation. +Storage for \tcode{v} +is allocated in an unspecified manner +except as noted in \ref{basic.stc.dynamic.allocation}. +The lifetime of \tcode{v} +persists for the duration +of the invocation of the contract-violation handler. + +\pnum +If the contract violation occurred +because the evaluation of the predicate +exited via an exception, +the contract-violation handler is invoked +from within an active implicit handler +for that exception\iref{except.handle}. +If the contract-violation handler +returns normally +and the evaluation semantic is observe, +that implicit handler +is no longer considered active. + +\begin{note} +The exception can be inspected or rethrown within the contract-violation handler. +\end{note} + +\pnum +\indextext{contract evaluation semantics!enforce}% +If the contract-violation handler +returns normally +and the evaluation semantic is enforce, +the program is contract-terminated; +if violation occurred +as the result of an uncaught exception +from the evaluation of the predicate, +the implicit handler +remains active when contract termination occurs. + +\pnum +\indextext{contract evaluation semantics!observe}% +\begin{note} +If the contract-violation handler +returns normally +and the evaluation semantic is observe, +control flow continues normally +after the point of evaluation of the contract assertion. +\end{note} + +\pnum +There is an observable checkpoint\iref{intro.abstract} $C$ +that happens after the contract-violation handler returns normally +such that any other operation $O$ +that happens after the contract-violation handler returns +also happens after $C$. + +\pnum +\begin{note} +The terminating semantics terminate the program +if execution would otherwise continue normally +past a contract violation: +the enforce semantic provides the opportunity to +log information about the contract violation +before terminating the program +or to throw an exception to avoid termination, +and the quick-enforce semantic is intended +to terminate the program as soon as possible +as well as +to minimize the impact of contract checks +on the generated code size. +Conversely, +the observe semantic +provides the opportunity to +log information about the contract violation +without having to terminate the program. +\end{note} + +\pnum +If a contract-violation handler +invoked from the evaluation of a function contract assertion\iref{dcl.contract.func} +exits via an exception, +the behavior is as if +the function body exits via that same exception. +\begin{note} +A \grammarterm{function-try-block}\iref{except.pre} +is the function body when present +and thus does not +have an opportunity to catch the exception. +If the function +has a non-throwing exception specification, +the function \tcode{std::terminate} is invoked\iref{except.terminate}. +\end{note} + +\begin{note} +If a contract-violation handler +invoked from an \grammarterm{assertion-statement}\iref{stmt.contract.assert} +exits via an exception, +the search for a handler +continues from the execution of that statement. +\end{note} + +\pnum +To \defn{evaluate in sequence} a list $R$ of contract assertions: +\begin{itemize} +\item +Construct a list of contract assertions $S$ such that +\begin{itemize} +\item +all elements of $R$ are in $S$, +\item +each element of $R$ +may be repeated an +\impldef{maximum number of repeated evaluations of a contract assertion} +number of times +within $S$, and +\item +if a contract assertion $A$ +precedes another contract assertion $B$ +in $R$, +then the +first occurrence of $A$ +precedes the first occurrence of $B$ +in $S$. +\end{itemize} +\item +Evaluate each element of $S$ such that, +if a contract assertion $A$ +precedes a contract assertion $B$ +in $S$, +then the evaluation of $A$ +is sequenced before +the evaluation of $B$. +\end{itemize} + +\begin{example} +\begin{codeblock} +void f(int i) +{ + contract_assert(i > 0); // \#1 + contract_assert(i < 10); // \#2 + // valid sequence of evaluations: \#1 \#2 + // valid sequence of evaluations: \#1 \#1 \#2 \#2 + // valid sequence of evaluations: \#1 \#2 \#1 \#2 + // valid sequence of evaluations: \#1 \#2 \#2 \#1 + // invalid sequence of evaluations: \#2 \#1 +} +\end{codeblock} +\end{example} + +\pnum +\recommended +An implementation should +provide an option to perform +a specified number of repeated evaluations +for contract assertions. +By default, +no repeated evaluations should be performed. + +\rSec2[basic.contract.handler]{Contract-violation handler} + +\pnum +\indextext{\idxcode{contract_violation}}% +\indexlibraryglobal{contract_violation}% +The \defn{contract-violation handler} +of a program is a function named +\tcode{::handle_contract_violation}. +The contract-violation handler +shall have a single parameter +of type +``lvalue reference to \keyword{const} \tcode{std::\-contracts::\-contract_violation}'' +and shall return \tcode{void}. +The contract-violation handler +may have a non-throwing exception specification. +The implementation +shall provide a definition of the contract-violation handler, +called the \defnadj{default}{contract-violation handler}. +\begin{note} +No declaration +for the default contract-violation handler +is provided by +any standard library header. +\end{note} + +\pnum +\recommended +The default contract-violation handler +should produce diagnostic output +that suitably formats the most relevant contents +of the \tcode{std::contracts::contract_violation} object, +rate-limited for potentially repeated violations +of observed contract assertions, +and then return normally. + +\pnum +It is +\impldef{replaceability of the contract-violation handler} +whether the contract-violation handler +is replaceable\iref{dcl.fct.def.replace}. +If the contract-violation handler +is not replaceable, +a declaration of a replacement function for the contract-violation handler +is ill-formed, no diagnostic required. + +\indextext{contract assertion|)} diff --git a/source/classes.tex b/source/classes.tex index c9da349462..3a80fc1528 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -36,7 +36,7 @@ \begin{bnf} \nontermdef{class-head}\br - class-key \opt{attribute-specifier-seq} class-head-name \opt{class-virt-specifier} \opt{base-clause}\br + class-key \opt{attribute-specifier-seq} class-head-name \opt{class-property-specifier-seq} \opt{base-clause}\br class-key \opt{attribute-specifier-seq} \opt{base-clause} \end{bnf} @@ -46,8 +46,15 @@ \end{bnf} \begin{bnf} -\nontermdef{class-virt-specifier}\br - \keyword{final} +\nontermdef{class-property-specifier-seq}\br + class-property-specifier \opt{class-property-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{class-property-specifier}\br + \keyword{final}\br + \keyword{trivially_relocatable_if_eligible}\br + \keyword{replaceable_if_eligible} \end{bnf} \begin{bnf} @@ -120,12 +127,13 @@ \end{note} \pnum -If a class is marked with the \grammarterm{class-virt-specifier} \tcode{final} and it appears -as a \grammarterm{class-or-decltype} in a \grammarterm{base-clause}\iref{class.derived}, -the program is ill-formed. Whenever a -\grammarterm{class-key} is followed by a \grammarterm{class-head-name}, the -\grammarterm{identifier} \tcode{final}, and a colon or left brace, \tcode{final} is -interpreted as a \grammarterm{class-virt-specifier}. +Each \grammarterm{class-property-specifier} shall appear at most once +within a single \grammarterm{class-property-specifier-seq}. +Whenever a \grammarterm{class-key} is followed +by a \grammarterm{class-head-name}, +the identifier \tcode{final}, \tcode{trivially_relocatable_if_eligible}, +or \tcode{replaceable_if_eligible}, and a colon or left brace, +the identifier is interpreted as a \grammarterm{class-property-specifier}. \begin{example} \begin{codeblock} struct A; @@ -134,12 +142,19 @@ struct X { struct C { constexpr operator int() { return 5; } }; - struct B final : C{}; // OK, definition of nested class \tcode{B}, - // not declaration of a bit-field member \tcode{final} + struct B trivially_relocatable_if_eligible : C{}; + // OK, definition of nested class \tcode{B}, + // not declaration of a bit-field member + // \tcode{trivially_relocatable_if_eligible} }; \end{codeblock} \end{example} +\pnum +If a class is marked with the \grammarterm{class-property-specifier} +\tcode{final} and that class appears as a \grammarterm{class-or-decltype} +in a \grammarterm{base-clause}\iref{class.derived}, the program is ill-formed. + \pnum \begin{note} Complete objects of class type have nonzero size. @@ -150,7 +165,7 @@ \pnum \begin{note} -Class objects can be assigned\iref{over.ass,class.copy.assign}, +Class objects can be assigned\iref{over.assign,class.copy.assign}, passed as arguments to functions\iref{dcl.init,class.copy.ctor}, and returned by functions (except objects of classes for which copying or moving has been restricted; see~\ref{dcl.fct.def.delete} and \ref{class.access}). @@ -173,12 +188,84 @@ \end{itemize} \pnum -A \defnadj{trivial}{class} is a class that is trivially copyable and -has one or more eligible default constructors\iref{class.default.ctor}, -all of which are trivial. +A class \tcode{C} is \defn{default-movable} if + +\begin{itemize} +\item overload resolution for direct-initializing an object of type \tcode{C} +from an xvalue of type \tcode{C} selects a constructor that is a direct member +of \tcode{C} and is neither user-provided nor deleted, + +\item overload resolution for assigning to an lvalue of type \tcode{C} from an +xvalue of type \tcode{C} selects an assignment operator function that is a +direct member of \tcode{C} and is neither user-provided nor deleted, and + +\item \tcode{C} has a destructor that is neither user-provided nor deleted. +\end{itemize} + +\pnum +A class is \defn{eligible for trivial relocation} unless it +\begin{itemize} +\item has any virtual base classes, +\item has a base class that is not a trivially relocatable class, +\item has a non-static data member of an object type that is not of a +trivially relocatable type, or + +\item has a deleted destructor, +\end{itemize} +except that it is \impldef{whether an otherwise-eligible union having one or +more subobjects of polymorphic class type is eligible for trivial relocation} +whether an otherwise-eligible union having one or more subobjects of +polymorphic class type is eligible for trivial relocation. + +\pnum +A class \tcode{C} is a \defnadj{trivially relocatable}{class} +if it is eligible for trivial relocation and +\begin{itemize} +\item has the \tcode{trivially_relocatable_if_eligible} \grammarterm{class-property-specifier}, +\item is a union with no user-declared special member functions, or +\item is default-movable. +\end{itemize} + +\pnum \begin{note} -In particular, a trivially copyable or trivial class does not have -virtual functions or virtual base classes. +A class with const-qualified or reference non-static data members can be +trivially relocatable. +\end{note} + +\pnum +A class \tcode{C} is \defn{eligible for replacement} unless +\begin{itemize} +\item it has a base class that is not a replaceable class, +\item it has a non-static data member that is not of a replaceable type, +\item overload resolution fails or selects a deleted constructor when +direct-initializing an object of type \tcode{C} from an xvalue of type +\tcode{C}\iref{dcl.init.general}, + +\item overload resolution fails or selects a deleted assignment operator +function when assigning to an lvalue of type \tcode{C} from an xvalue of type +\tcode{C} \iref{expr.assign,over.assign}), or + +\item it has a deleted destructor. +\end{itemize} + +\pnum +A class \tcode{C} is a \defnadj{replaceable}{class} if it is +eligible for replacement and +\begin{itemize} +\item has the \tcode{replaceable_if_eligible} \grammarterm{class-property-specifier}, +\item is a union with no user-declared special member functions, or +\item is default-movable. +\end{itemize} + +\pnum +\begin{note} +Accessibility of the special member functions is not considered when +establishing trivial relocatability or replaceability. +\end{note} + +\pnum +\begin{note} +Not all trivially copyable classes are trivially relocatable or replaceable. \end{note} \pnum @@ -266,31 +353,31 @@ \begin{note} Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified -in~\ref{class.mem}. +in~\ref{class.mem.general} and~\ref{expr.rel}. \end{note} \pnum \begin{example} \begin{codeblock} -struct N { // neither trivial nor standard-layout +struct N { // neither trivially copyable nor standard-layout int i; int j; virtual ~N(); }; -struct T { // trivial but not standard-layout +struct T { // trivially copyable but not standard-layout int i; private: int j; }; -struct SL { // standard-layout but not trivial +struct SL { // standard-layout but not trivially copyable int i; int j; ~SL(); }; -struct POD { // both trivial and standard-layout +struct POD { // both trivially copyable and standard-layout int i; int j; }; @@ -431,7 +518,8 @@ \begin{note} The declaration of a class name takes effect immediately after the \grammarterm{identifier} is seen in the class definition or -\grammarterm{elaborated-type-specifier}. For example, +\grammarterm{elaborated-type-specifier}. +\begin{example} \begin{codeblock} class A * A; \end{codeblock} @@ -439,6 +527,7 @@ it as the name of a pointer to an object of that class. This means that the elaborated form \keyword{class} \tcode{A} must be used to refer to the class. Such artistry with names can be confusing and is best avoided. +\end{example} \end{note} \pnum @@ -482,16 +571,15 @@ \begin{bnf} \nontermdef{member-declarator}\br - declarator \opt{virt-specifier-seq} \opt{pure-specifier}\br - declarator requires-clause\br + declarator \opt{virt-specifier-seq} \opt{function-contract-specifier-seq} \opt{pure-specifier}\br + declarator requires-clause \opt{function-contract-specifier-seq}\br declarator brace-or-equal-initializer\br \opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} \end{bnf} \begin{bnf} \nontermdef{virt-specifier-seq}\br - virt-specifier\br - virt-specifier-seq virt-specifier + virt-specifier \opt{virt-specifier-seq} \end{bnf} \begin{bnf} @@ -535,6 +623,12 @@ the program is ill-formed; see~\ref{temp.spec.general}. \end{note} +\pnum +The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func}) +in a \grammarterm{member-declarator} +shall be present only if +the \grammarterm{declarator} declares a function. + \pnum \indextext{definition!class}% The \grammarterm{member-specification} in a class definition declares the @@ -626,7 +720,8 @@ \item function body\iref{dcl.fct.def.general}, \item default argument\iref{dcl.fct.default}, \item default template argument\iref{temp.param}, -\item \grammarterm{noexcept-specifier}\iref{except.spec}, or +\item \grammarterm{noexcept-specifier}\iref{except.spec}, +\item \grammarterm{function-contract-specifier}\iref{dcl.contract.func}, or \item default member initializer \end{itemize} within the \grammarterm{member-specification} of the class or class template. @@ -948,8 +1043,8 @@ A member function can be declared (but not defined) using a typedef for a function type. The resulting member function has exactly the same type as it would have if the function declarator were provided explicitly, -see~\ref{dcl.fct}. For example, - +see~\ref{dcl.fct} and \ref{temp.arg}. +\begin{example} \begin{codeblock} typedef void fv(); typedef void fvc() const; @@ -962,8 +1057,7 @@ fv S::* pmfv2 = &S::memfunc2; fvc S::* pmfv3 = &S::memfunc3; \end{codeblock} - -Also see~\ref{temp.arg}. +\end{example} \end{note} \rSec2[class.mfct.non.static]{Non-static member functions}% @@ -1058,7 +1152,7 @@ \end{example} \pnum -Two special member functions are of the same kind if: +Two special member functions are of the same kind if \begin{itemize} \item they are both default constructors, \item they are both copy or move constructors @@ -1216,7 +1310,7 @@ has a default argument (including the case of a constructor with no parameters). \indextext{implicitly-declared default constructor}% -If there is no user-declared constructor for class +If there is no user-declared constructor or constructor template for class \tcode{X}, a non-explicit constructor having no parameters is implicitly declared as defaulted\iref{dcl.fct.def}. @@ -1224,56 +1318,50 @@ inline public member of its class. \pnum -A defaulted default constructor for class \tcode{X} is defined as deleted if: +A defaulted default constructor for class \tcode{X} is defined as deleted if \begin{itemize} \item any non-static data member with no default member initializer\iref{class.mem} is of reference type, -\item any non-variant non-static data member of const-qualified type -(or possibly multi-dimensional array thereof) +\item \tcode{X} is a non-union class and +any non-variant non-static data member of const-qualified type +(or possibly multidimensional array thereof) with no \grammarterm{brace-or-equal-initializer} is not const-default-constructible\iref{dcl.init}, -\item \tcode{X} is a union and all of its variant members are of const-qualified -type (or possibly multi-dimensional array thereof), - -\item \tcode{X} is a non-union class and all members of any anonymous union member are -of const-qualified type (or possibly multi-dimensional array thereof), - -\item any potentially constructed subobject, except for a non-static data member -with a \grammarterm{brace-or-equal-initializer} -or a variant member of a union where another non-static data member -has a \grammarterm{brace-or-equal-initializer}, -has class type \tcode{M} (or possibly multi-dimensional array thereof) +\item any non-variant potentially constructed subobject, except for a non-static data member +with a \grammarterm{brace-or-equal-initializer}, +has class type \tcode{M} (or possibly multidimensional array thereof) and overload resolution\iref{over.match} as applied to find \tcode{M}'s corresponding constructor -either does not result in a usable candidate\iref{over.match.general} -or, in the case of a variant member, selects a non-trivial function, or +does not result in a usable candidate\iref{over.match.general}, or -\item any potentially constructed subobject has -class type \tcode{M} (or possibly multi-dimensional array thereof) and +\item any potentially constructed subobject $S$ has +class type \tcode{M} (or possibly multidimensional array thereof), \tcode{M} has a destructor that is deleted or inaccessible from the defaulted default -constructor. +constructor, and +either $S$ is non-variant or $S$ has a default member initializer. \end{itemize} \pnum -A default constructor is +A default constructor for a class \tcode{X} is \defnx{trivial}{constructor!default!trivial} -if it is not user-provided and if: +if it is not user-provided and if \begin{itemize} \item -its class has no virtual functions\iref{class.virtual} and no virtual base +\tcode{X} has no virtual functions\iref{class.virtual} and no virtual base classes\iref{class.mi}, and -\item no non-static data member of its class has +\item no non-static data member of \tcode{X} has a default member initializer\iref{class.mem}, and \item -all the direct base classes of its class have trivial default constructors, and +all the direct base classes of \tcode{X} have trivial default constructors, and \item -for all the non-static data members of its class that are of class +either \tcode{X} is a union or +for all the non-variant non-static data members of \tcode{X} that are of class type (or array thereof), each such class has a trivial default constructor. \end{itemize} @@ -1281,7 +1369,18 @@ \defnx{non-trivial}{constructor!default!non-trivial}. \pnum -An implicitly-defined\iref{dcl.fct.def.default} default constructor performs the set of +If a default constructor of a union-like class \tcode{X} is trivial, +then for each union \tcode{U} +that is either \tcode{X} or an anonymous union member of \tcode{X}, +if the first variant member, if any, of \tcode{U} +has implicit-lifetime type\iref{basic.types.general}, +the default constructor of \tcode{X} begins the lifetime of that member +if it is not the active member of its union. +\begin{note} +It is already the active member if \tcode{U} was value-initialized. +\end{note} +Otherwise, +an implicitly-defined\iref{dcl.fct.def.default} default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no \grammarterm{ctor-initializer}\iref{class.base.init} and an empty @@ -1518,14 +1617,14 @@ \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: \begin{itemize} \item a potentially constructed subobject of type - \tcode{M} (or possibly multi-dimensional array thereof) for which + \tcode{M} (or possibly multidimensional array thereof) for which overload resolution\iref{over.match}, as applied to find \tcode{M}'s corresponding constructor, either does not result in a usable candidate\iref{over.match.general} or, in the case of a variant member, selects a non-trivial function, \item any potentially constructed subobject of - class type \tcode{M} (or possibly multi-dimensional array thereof) + class type \tcode{M} (or possibly multidimensional array thereof) where \tcode{M} has a destructor that is deleted or inaccessible from the defaulted constructor, or, @@ -1547,7 +1646,7 @@ \tcode{X} is trivial -if it is not user-provided and if: +if it is not user-provided and if \begin{itemize} \item class @@ -1594,7 +1693,7 @@ \tcode{X} performs a memberwise copy/move of its bases and members. \begin{note} -Default member initializers of non-static data members are ignored. See also the example in~\ref{class.base.init}. +Default member initializers of non-static data members are ignored. \end{note} The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see~\ref{class.base.init}). @@ -1788,12 +1887,12 @@ class \tcode{X} is defined as deleted if \tcode{X} has: \begin{itemize} \item a non-static data member of \keyword{const} non-class - type (or possibly multi-dimensional array thereof), or + type (or possibly multidimensional array thereof), or \item a non-static data member of reference type, or \item a direct non-static data member of class type \tcode{M} - (or possibly multi-dimensional array thereof) or + (or possibly multidimensional array thereof) or a direct base class \tcode{M} that cannot be copied/moved because overload resolution \iref{over.match}, as applied to find \tcode{M}'s corresponding @@ -1813,7 +1912,7 @@ Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a base class copy/move assignment operator is always hidden -by the corresponding assignment operator of a derived class\iref{over.ass}. +by the corresponding assignment operator of a derived class\iref{over.assign}. \begin{note} A \grammarterm{using-declaration} in a derived class \tcode{C} that names an assignment operator from a base class @@ -1831,7 +1930,7 @@ \tcode{X} is trivial -if it is not user-provided and if: +if it is not user-provided and if \begin{itemize} \item class @@ -2029,27 +2128,42 @@ \pnum A defaulted destructor for a class - \tcode{X} is defined as deleted if: + \tcode{X} is defined as deleted if \begin{itemize} -\item any potentially constructed subobject has class type - \tcode{M} (or possibly multi-dimensional array thereof) and +\item \tcode{X} is a non-union class and + any non-variant potentially constructed subobject has class type + \tcode{M} (or possibly multidimensional array thereof) where \tcode{M} has a destructor that is deleted or - is inaccessible from the defaulted destructor or, - in the case of a variant member, is non-trivial, + is inaccessible from the defaulted destructor, -\item or, for a virtual destructor, lookup of the non-array deallocation +\item + \tcode{X} is a union and + \begin{itemize} + \item + overload resolution to select a constructor to + default-initialize an object of type \tcode{X} either fails or + selects a constructor that is either deleted or not trivial, or + \item + \tcode{X} has a variant member \tcode{V} of + class type \tcode{M} (or possibly multi-dimensional array thereof) + where \tcode{V} has a default member initializer and + \tcode{M} has a destructor that is non-trivial, or, + \end{itemize} + +\item for a virtual destructor, lookup of the non-array deallocation function results in an ambiguity or in a function that is deleted or inaccessible from the defaulted destructor. \end{itemize} \pnum -A destructor is trivial if it is not user-provided and if: +A destructor for a class \tcode{X} is trivial if it is not user-provided and if \begin{itemize} \item the destructor is not virtual, -\item all of the direct base classes of its class have trivial destructors, and +\item all of the direct base classes of \tcode{X} have trivial destructors, and -\item for all of the non-static data members of its class that are of class +\item either \tcode{X} is a union or +for all of the non-variant non-static data members of \tcode{X} that are of class type (or array thereof), each such class has a trivial destructor. \end{itemize} @@ -2221,7 +2335,7 @@ Such use of explicit placement and destruction of objects can be necessary to cope with dedicated hardware resources and for writing memory management facilities. -For example, +\begin{example} \begin{codeblock} void* operator new(std::size_t, void* p) { return p; } struct X { @@ -2237,6 +2351,7 @@ p->X::~X(); // cleanup } \end{codeblock} +\end{example} \end{note} \pnum @@ -2292,8 +2407,7 @@ \pnum \begin{note} -See~\ref{over.match} for a discussion of the use of conversions in function calls -as well as examples below. +See~\ref{over.match} for a discussion of the use of conversions in function calls. \end{note} \pnum @@ -2324,8 +2438,6 @@ specifies a conversion from the types of its parameters (if any) to the type of its class. -Such a constructor is called a -\defnadj{converting}{constructor}. \begin{example} \indextext{Jessie}% \begin{codeblock} @@ -2376,14 +2488,6 @@ \end{example} \end{note} -\pnum -A non-explicit copy/move constructor\iref{class.copy.ctor} is -a converting constructor. -\begin{note} -An implicitly-declared copy/move constructor is not an explicit constructor; -it can be called for implicit type conversions. -\end{note} - \rSec3[class.conv.fct]{Conversion functions}% \indextext{function!conversion}% \indextext{fundamental type conversion|see{conversion, user-defined}}% @@ -2867,7 +2971,7 @@ refers to an object of class type with a virtual destructor, because the deallocation function is chosen by the destructor of the dynamic type of the object, the effect is the same in that case. -For example, +\begin{example} \begin{codeblock} struct B { virtual ~B(); @@ -2903,6 +3007,7 @@ and its storage is deallocated by \tcode{E::operator delete()}, due to the virtual destructor. +\end{example} \end{note} \begin{note} Virtual destructors have no effect on the deallocation function actually @@ -2911,7 +3016,7 @@ of a \grammarterm{delete-expression} refers to an array of objects of class type. -For example, +\begin{example} \begin{codeblock} struct B { virtual ~B(); @@ -2929,6 +3034,7 @@ delete[] bp; // undefined behavior } \end{codeblock} +\end{example} \end{note} \pnum @@ -3069,14 +3175,14 @@ base classes. A union shall not be used as a base class. \indextext{restriction!\idxcode{union}}% If a union contains a non-static data member of -reference type the program is ill-formed. -\begin{note} -Absent default member initializers\iref{class.mem}, -if any non-static data member of a union has a non-trivial -default constructor\iref{class.default.ctor}, -copy constructor, move constructor\iref{class.copy.ctor}, -copy assignment operator, move assignment operator\iref{class.copy.assign}, -or destructor\iref{class.dtor}, the corresponding member function +reference type, the program is ill-formed. +\begin{note} +If any non-static data member of a union has a non-trivial +copy constructor, +move constructor\iref{class.copy.ctor}, +copy assignment operator, or +move assignment operator\iref{class.copy.assign}, +the corresponding member function of the union must be user-provided or it will be implicitly deleted\iref{dcl.fct.def.delete} for the union. \begin{example} @@ -3089,11 +3195,11 @@ }; \end{codeblock} Since \tcode{std::string}\iref{string.classes} declares non-trivial versions of all of the special -member functions, \tcode{U} will have an implicitly deleted default constructor, -copy/move constructor, -copy/move assignment operator, and destructor. -To use \tcode{U}, some or all of these member functions -must be user-provided. +member functions, \tcode{U} will have an implicitly deleted +copy/move constructor and copy/move assignment operator. +The default constructor and destructor of \tcode{U} are both trivial +even though \tcode{std::string} has +a non-trivial default constructor and a non-trivial destructor. \end{example} \end{note} @@ -3125,7 +3231,7 @@ Otherwise, $S(\mathtt{E})$ is empty. \end{itemize} In an assignment expression of the form \tcode{E1 = E2} -that uses either the built-in assignment operator\iref{expr.ass} +that uses either the built-in assignment operator\iref{expr.assign} or a trivial assignment operator\iref{class.copy.assign}, for each element \tcode{X} of $S($\tcode{E1}$)$ and each anonymous union member \tcode{X}\iref{class.union.anon} that @@ -3328,13 +3434,13 @@ \pnum \indextext{nested class!local class}% -If class \tcode{X} is a local class, a nested class \tcode{Y} may be -declared in class \tcode{X} and later defined in the definition of class -\tcode{X} or be later defined in the same scope as the definition of -class \tcode{X}. \indextext{restriction!local class}% A class nested within a local class is a local class. +A member of a local class \tcode{X} shall be +declared only in the definition of \tcode{X} or, +if the member is a nested class, +in the nearest enclosing block scope of \tcode{X}. \pnum \indextext{restriction!static member local class}% @@ -3705,13 +3811,13 @@ determining overriding. \end{footnote} $F$. -For convenience we say that any virtual function overrides itself. +For convenience, we say that any virtual function overrides itself. \indextext{overrider!final}% A virtual member function $V$ of a class object $S$ is a \defn{final overrider} unless the most derived class\iref{intro.object} of which $S$ is a base class subobject (if any) has another member function that overrides $V$. In a derived class, if a virtual member function of a base class subobject -has more than one final overrider the program is ill-formed. +has more than one final overrider, the program is ill-formed. \begin{example} \begin{codeblock} struct A { @@ -4243,8 +4349,7 @@ Because access control applies to the declarations named, if access control is applied to a \grammarterm{typedef-name}, only the accessibility of the typedef or alias declaration itself is considered. The accessibility of the entity referred to by the \grammarterm{typedef-name} is not considered. -For example, - +\begin{example} \begin{codeblock} class A { class B { }; @@ -4257,6 +4362,7 @@ A::B y; // access error, \tcode{A::B} is private } \end{codeblock} +\end{example} \end{note} \pnum @@ -4286,8 +4392,8 @@ \begin{codeblock} class A { typedef int I; // private member - I f(); - friend I g(I); + I f() pre(A::x > 0); + friend I g(I) post(A::x <= 0); static I x; template struct Q; template friend struct R; @@ -4295,8 +4401,8 @@ struct B { }; }; -A::I A::f() { return 0; } -A::I g(A::I p = A::x); +A::I A::f() pre(A::x > 0) { return 0; } +A::I g(A::I p = A::x) post(A::x <= 0); A::I g(A::I p) { return 0; } A::I A::x = 0; template struct A::Q { }; @@ -4521,8 +4627,7 @@ a conversion from a pointer to a derived class to a pointer to an inaccessible base class can be ill-formed if an implicit conversion is used, but well-formed if an explicit cast is used. -For example, - +\begin{example} \begin{codeblock} class B { public: @@ -4547,6 +4652,7 @@ bp2->mi = 3; // OK, access through a pointer to \tcode{B}. } \end{codeblock} +\end{example} \end{note} \pnum @@ -4857,12 +4963,6 @@ \end{codeblock} \end{example} -\pnum -\indextext{friend function!linkage of}% -A function first declared in a friend declaration -has the linkage of the namespace of which it is a member\iref{basic.link}. -Otherwise, the function retains its previous linkage\iref{dcl.stc}. - \pnum \indextext{declaration!overloaded name and \tcode{friend}}% \begin{note} @@ -5237,7 +5337,7 @@ \end{example} \begin{note} \indextext{initialization!overloaded assignment and}% -Overloading of the assignment operator\iref{over.ass} +Overloading of the assignment operator\iref{over.assign} has no effect on initialization. \end{note} @@ -5298,7 +5398,7 @@ If \tcode{T} is a class type with no default constructor, -any declaration of an object of type +any initializing declaration of an object of type \tcode{T} (or array thereof) is ill-formed if no \grammarterm{initializer} @@ -5718,18 +5818,27 @@ \pnum \indextext{initialization!member function call during}% Member functions (including virtual member functions, \ref{class.virtual}) can be -called for an object under construction. -Similarly, an object under construction can be the operand of the +called for an object under construction or destruction. +Similarly, an object under construction or destruction can be the operand of the \tcode{typeid} operator\iref{expr.typeid} or of a \keyword{dynamic_cast}\iref{expr.dynamic.cast}. -However, if these operations are performed in a -\grammarterm{ctor-initializer} +However, if these operations are performed +during evaluation of +\begin{itemize} +\item +a \grammarterm{ctor-initializer} (or in a function called directly or indirectly from a \grammarterm{ctor-initializer}) before all the \grammarterm{mem-initializer}{s} -for base classes have completed, the program has undefined behavior. +for base classes have completed, +\item +a precondition assertion of a constructor, or +\item +a postcondition assertion of a destructor\iref{dcl.contract.func}, +\end{itemize} +the program has undefined behavior. \begin{example} \begin{codeblock} class A { @@ -5945,7 +6054,7 @@ B bobj; // definition of \tcode{bobj} extern X xobj; -int* p3 = &xobj.i; // OK, \tcode{X} is a trivial class +int* p3 = &xobj.i; // OK, all constructors of \tcode{X} are trivial X xobj; \end{codeblock} For another example, @@ -5963,11 +6072,12 @@ \pnum During the construction of an object, -if the value of the object or any of its subobjects is -accessed through a glvalue that is not obtained, directly or indirectly, from +if the value of any of its subobjects +or any element of its object representation +is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's \keyword{this} -pointer, the value of the object or subobject thus obtained is unspecified. +pointer, the value thus obtained is unspecified. \begin{example} \begin{codeblock} struct C; @@ -6052,6 +6162,9 @@ or from a destructor, including during the construction or destruction of the class's non-static data members, +or during the evaluation of +a postcondition assertion of a constructor or +a precondition assertion of a destructor\iref{dcl.contract.func}, and the object to which the call applies is the object (call it \tcode{x}) under construction or destruction, the function called is the @@ -6181,25 +6294,26 @@ \indextext{constructor!copy!elision}% \indextext{constructor!move!elision}% When certain criteria are met, an implementation is -allowed to omit the copy/move construction of a class object, -even if the constructor selected for the copy/move operation and/or the +allowed to omit the creation of a class object from +a source object of the same type (ignoring cv-qualification), +even if the selected constructor and/or the destructor for the object have \indextext{side effects}% side effects. In such cases, the implementation treats the source and target of the -omitted copy/move operation as simply two different ways of +omitted initialization as simply two different ways of referring to the same object. If the first parameter of the selected constructor is an rvalue reference to the object's type, the destruction of that object occurs when the target would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects would have been destroyed without the optimization. -\begin{footnote} +\begin{note} Because only one object is destroyed instead of two, -and one copy/move constructor -is not executed, there is still one object destroyed for each one constructed. -\end{footnote} -This elision of copy/move operations, called +and the creation of one object is omitted, +there is still one object destroyed for each one constructed. +\end{note} +This elision of object creation, called \indexdefn{copy elision|see{constructor, copy, elision}}% \indexdefn{elision!copy|see{constructor, copy, elision}}% \indexdefn{constructor!copy!elision}\indexdefn{constructor!move!elision}\term{copy elision}, @@ -6207,34 +6321,35 @@ following circumstances (which may be combined to eliminate multiple copies): \begin{itemize} -\item in a \tcode{return} statement in a function with a class return type, +\item in a \tcode{return} statement\iref{stmt.return} in +a function with a class return type, when the \grammarterm{expression} is the name of a non-volatile -object with automatic storage duration (other than a function parameter or a variable +object $o$ with automatic storage duration (other than a function parameter or a variable introduced by the \grammarterm{exception-declaration} of a -\grammarterm{handler}\iref{except.handle}) -with the same type (ignoring cv-qualification) as -the function return type, the copy/move operation can be -omitted by constructing the object directly -into the function call's return object +\grammarterm{handler}\iref{except.handle}), +the copy-initialization of the result object can be +omitted by constructing $o$ directly +into the function call's result object; \item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand -is the name of a non-volatile object with automatic storage duration -(other than a function or catch-clause parameter) +is the name of a non-volatile object $o$ with automatic storage duration +(other than a function parameter or +a variable introduced by +the \grammarterm{exception-declaration} of a \grammarterm{handler}) that belongs to a scope that does not contain the innermost enclosing \grammarterm{compound-statement} associated with a \grammarterm{try-block} (if there is one), -the copy/move operation can be omitted by -constructing the object directly into the exception object +the copy-initialization of the exception object can be omitted by +constructing $o$ directly into the exception object; \item in a coroutine\iref{dcl.fct.def.coroutine}, a copy of a coroutine parameter can be omitted and references to that copy replaced with references to the corresponding parameter if the meaning of the program will be unchanged except for -the execution of a constructor and destructor for the parameter copy object +the execution of a constructor and destructor for the parameter copy object; \item when the \grammarterm{exception-declaration} of a -\grammarterm{handler}\iref{except.handle} declares an object of the same -type (except for cv-qualification) as the exception -object\iref{except.throw}, the copy operation can be omitted by treating +\grammarterm{handler}\iref{except.handle} declares an object $o$, +the copy-initialization of $o$ can be omitted by treating the \grammarterm{exception-declaration} as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the @@ -6563,7 +6678,8 @@ \tcode{static_cast(a <=> b)}. \item -Otherwise, if overload resolution for \tcode{a <=> b} is performed and +Otherwise, if \tcode{a <=> b} is usable or +overload resolution for \tcode{a <=> b} is performed and finds at least one viable candidate, the synthesized three-way comparison is not defined. diff --git a/source/compatibility.tex b/source/compatibility.tex index e3ff48606f..2e4d0d5bb6 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -8,9 +8,26 @@ \pnum \indextext{summary!compatibility with ISO \CppXXIII{}}% Subclause \ref{diff.cpp23} lists the differences between \Cpp{} and -ISO \CppXXIII{} (ISO/IEC 14882:2023, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppXXIII{}, by the chapters of this document. +\rSec2[diff.cpp23.lex]{\ref{lex}: Lexical conventions} + +\diffref{lex.key} +\change +New keywords. +\rationale +Required for new features. +\begin{itemize} +\item +The \keyword{contract_assert} keyword +is added to introduce a contract assertion +through an \grammarterm{assertion-statement}\iref{stmt.contract.assert}. +\end{itemize} +\effect +Valid \CppXXIII{} code using \keyword{contract_assert} as an identifier +is not valid in this revision of \Cpp{}. + \rSec2[diff.cpp23.expr]{\ref{expr}: expressions} \diffref{expr.arith.conv} @@ -23,7 +40,7 @@ A valid \CppXXIII{} program that performs operations mixing a value of an enumeration type and a value of a different enumeration type or of a floating-point type is ill-formed. -For example: +\begin{example} \begin{codeblock} enum E1 { e }; enum E2 { f }; @@ -31,8 +48,64 @@ int k = f - e; // ill-formed; previously well-formed auto x = true ? e : f; // ill-formed; previously well-formed \end{codeblock} +\end{example} + +\diffref{expr.rel,expr.eq} +\change +Comparing two objects of array type is no longer valid. +\rationale +The old behavior was confusing since it compared not the contents of the two +arrays, but their addresses. +\effect +A valid \CppXXIII{} program directly comparing two array objects is rejected as +ill-formed in this document. +\begin{example} +\begin{codeblock} +int arr1[5]; +int arr2[5]; +bool same = arr1 == arr2; // ill-formed; previously well-formed +bool idem = arr1 == +arr2; // compare addresses +bool less = arr1 < +arr2; // compare addresses, unspecified result +\end{codeblock} +\end{example} -\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: Declarations} +\diffref{expr.delete} +\change +Calling \tcode{delete} on a pointer to an incomplete class is ill-formed. +\rationale +Reduce undefined behavior. +\effect +A valid \CppXXIII{} program that calls \tcode{delete} on an incomplete +class type is ill-formed. +\begin{example} +\begin{codeblock} +struct S; + +void f(S *p) { + delete p; // ill-formed; previously well-formed +} + +struct S {}; +\end{codeblock} +\end{example} + +\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl}: declarations} + +\diffref{dcl.decl.general} +\change +Introduction of \tcode{trivially_relocatable_if_eligible} and +\tcode{replaceable_if_eligible} as identifiers with special meaning\iref{lex.name}. +\rationale +Support declaration of trivially relocatable and replaceable types\iref{class.prop}. +\effect +Valid \CppXXIII{} code can become ill-formed. +\begin{example} +\begin{codeblock} +struct C {}; +struct C replaceable_if_eligible {}; // was well-formed (new variable \tcode{replaceable_if_eligible}) + // now ill-formed (redefines \tcode{C}) +\end{codeblock} +\end{example} \diffref{dcl.init.list} \change @@ -44,13 +117,14 @@ Valid \CppXXIII{} code that relies on the result of pointer comparison between backing arrays may change behavior. -For example: +\begin{example} \begin{codeblock} bool ne(std::initializer_list a, std::initializer_list b) { return a.begin() != b.begin() + 1; } bool b = ne({2,3}, {1,2,3}); // unspecified result; previously \tcode{false} \end{codeblock} +\end{example} \diffref{dcl.array} \change @@ -61,7 +135,7 @@ \effect Valid \CppXXIII{} code that declares a pack of parameters without specifying a \grammarterm{declarator-id} becomes ill-formed. -For example: +\begin{example} \begin{codeblock} template void f(T... [1]); @@ -72,6 +146,65 @@ g(nullptr, nullptr); // ok } \end{codeblock} +\end{example} + +\rSec2[diff.cpp23.temp]{\ref{temp}: templates} + +\diffref{temp.constr} +\change +Some atomic constraints become fold expanded constraints. +\rationale +Permit the subsumption of fold expressions. +\effect +Valid \CppXXIII{} code may become ill-formed. +\begin{example} +\begin{codeblock} +template struct A; +struct S { + static constexpr int compare(const S&) { return 1; } +}; + +template +void f(A *, A *) +requires (T::compare(U{}) && ...); // was well-formed (atomic constraint of type \tcode{bool}), + // now ill-formed (results in an atomic constraint of type \tcode{int}) +void g(A *ap) { + f(ap, ap); +} +\end{codeblock} +\end{example} + +\diffref{temp.deduct.call} +\change +Template argument deduction from overload sets succeeds in more cases. +\rationale +Allow consideration of constraints to disambiguate overload sets +used as parameters in function calls. +\effect +Valid \CppXXIII{} code may become ill-formed. +\begin{example} +\begin{codeblock} +template +void f(T &&, void (*)(T &&)); + +void g(int &); // \#1 +inline namespace A { + void g(short &&); // \#2 +} +inline namespace B { + void g(short &&); // \#3 +} + +void q() { + int x; + f(x, g); // ill-formed; previously well-formed, deducing \tcode{T = int\&} +} +\end{codeblock} +There is no change to the applicable deduction rules for +the individual \tcode{g} candidates: +Type deduction from \#1 does not succeed; +type deductions from \#2 and \#3 both succeed. +\end{example} \rSec2[diff.cpp23.library]{\ref{library}: library introduction} @@ -82,14 +215,31 @@ New functionality. \effect The following \Cpp{} headers are new: +\libheaderrefx{contracts}{support.contract}, \libheaderref{debugging}, \libheaderrefx{hazard_pointer}{hazard.pointer.syn}, +\libheaderref{hive}, +\libheaderrefx{inplace_vector}{inplace.vector.syn}, \libheaderref{linalg}, -\libheaderref{rcu}, and +\libheaderref{rcu}, +\libheaderref{simd}, +\libheaderref{stdbit.h}, +\libheaderref{stdckdint.h}, and \libheaderrefx{text_encoding}{text.encoding.syn}. Valid \CppXXIII{} code that \tcode{\#include}{s} headers with these names may be invalid in this revision of \Cpp{}. +\diffref{res.on.macro.definitions} +\change +Additional restrictions on macro names. +\rationale +Avoid hard to diagnose or non-portable constructs. +\effect +Names of special identifiers may not be used as macro names. +Valid \CppXXIII{} code that defines \tcode{replaceable_if_eligible} or +\tcode{trivially_relocatable_if_eligible} as macros is invalid +in this revision of \Cpp{}. + \rSec2[diff.cpp23.strings]{\ref{strings}: strings library} \diffref{string.conversions} @@ -101,12 +251,13 @@ \effect \tcode{to_string} and \tcode{to_wstring} function calls that take floating-point arguments may produce a different output. -For example: +\begin{example} \begin{codeblock} auto s = std::to_string(1e-7); // \tcode{"1e-07"} // previously \tcode{"0.000000"} with \tcode{'.'} possibly // changed according to the global C locale \end{codeblock} +\end{example} \rSec2[diff.cpp23.containers]{\ref{containers}: containers library} @@ -118,7 +269,7 @@ \effect Valid \CppXXIII{} code that relies on the lack of this constructor may refuse to compile, or change behavior in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} void one(pair); // \#1 void one(span); // \#2 @@ -132,6 +283,7 @@ any b[10]; int y = span{b, b + 10}.size(); // \tcode{y} is \tcode{2}; previously \tcode{10} \end{codeblock} +\end{example} \rSec2[diff.cpp23.depr]{\ref{depr}: compatibility features} @@ -144,7 +296,8 @@ would not use the one from the allocator base class. \effect It is simpler to correctly define an allocator class with an allocator base -class. For example: +class. +\begin{example} \begin{codeblock} template struct MyAlloc : allocator { @@ -154,6 +307,7 @@ static_assert(!allocator_traits>::is_always_equal); // Error in \CppXXIII{}, // OK in \CppXXVI{} \end{codeblock} +\end{example} \nodiffref \change @@ -183,7 +337,7 @@ \change Remove header \libnoheader{codecvt} and all its contents. \rationale -The header has been deprecated for the previous three editions of this standard +The header has been deprecated for the previous three editions of this document and no longer implements the current Unicode standard, supporting only the obsolete UCS-2 encoding. Ongoing support is at implementer's discretion, @@ -227,7 +381,7 @@ \tcode{wbuffer_convert}. \rationale These features were underspecified with no clear error reporting mechanism and -were deprecated for the last three editions of this standard. +were deprecated for the last three editions of this document. Ongoing support is at implementer's discretion, exercising freedoms granted by \ref{zombie.names}. \effect @@ -240,12 +394,15 @@ \pnum \indextext{summary!compatibility with ISO \CppXX{}}% Subclause \ref{diff.cpp20} lists the differences between \Cpp{} and -ISO \CppXX{} (ISO/IEC 14882:2020, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppXX{}, +in addition to those listed above, by the chapters of this document. \rSec2[diff.cpp20.lex]{\ref{lex}: lexical conventions} \diffref{lex.name} +\indextext{XID_Start}% +\indextext{XID_Continue}% \change Previously valid identifiers containing characters not present in \UAX{44} properties XID_Start or XID_Continue, or @@ -266,10 +423,11 @@ Concatenation of \grammarterm{string-literal}s with different \grammarterm{encoding-prefix}es is now ill-formed. -For example: +\begin{example} \begin{codeblock} auto c = L"a" U"b"; // was conditionally-supported; now ill-formed \end{codeblock} +\end{example} \rSec2[diff.cpp20.expr]{\ref{expr}: expressions} @@ -281,11 +439,12 @@ \effect Valid \CppXX{} code that relies on a returned \grammarterm{id-expression}'s being an lvalue may change behavior or fail to compile. -For example: +\begin{example} \begin{codeblock} decltype(auto) f(int&& x) { return (x); } // returns \tcode{int\&\&}; previously returned \tcode{int\&} int& g(int&& x) { return x; } // ill-formed; previously well-formed \end{codeblock} +\end{example} \diffref{expr.sub} \change @@ -295,13 +454,14 @@ \effect Valid \CppXX{} code that uses a comma expression within a subscript expression may fail to compile. -For example: +\begin{example} \begin{codeblock} arr[1, 2] // was equivalent to \tcode{arr[(1, 2)]}, // now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed \end{codeblock} +\end{example} -\rSec2[diff.cpp20.stmt]{\ref{stmt.stmt}: statements} +\rSec2[diff.cpp20.stmt]{\ref{stmt}: statements} \diffref{stmt.ranged} \change @@ -311,7 +471,7 @@ Improve usability of the range-based \keyword{for} statement. \effect Destructors of some temporary objects are invoked later. -For example: +\begin{example} \begin{codeblock} void f() { std::vector v = { 42, 17, 13 }; @@ -323,8 +483,9 @@ } } \end{codeblock} +\end{example} -\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp20.dcl]{\ref{dcl}: declarations} \diffref{dcl.init.string} \change @@ -337,7 +498,7 @@ may now be initialized with a UTF-8 string literal. This can affect initialization that includes arrays that are directly initialized within class types, typically aggregates. -For example: +\begin{example} \begin{codeblock} struct A { char8_t s[10]; @@ -353,6 +514,7 @@ f({u8""}); // ambiguous } \end{codeblock} +\end{example} \rSec2[diff.cpp20.temp]{\ref{temp}: templates} @@ -363,7 +525,7 @@ Facilitate generic handling of throwing and non-throwing functions. \effect Valid ISO \CppXX{} code may be ill-formed in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} template struct A { }; template void f(void (*)(A) noexcept(B)); @@ -372,6 +534,7 @@ f(g); // ill-formed; previously well-formed } \end{codeblock} +\end{example} \rSec2[diff.cpp20.library]{\ref{library}: library introduction} @@ -408,7 +571,7 @@ Valid \CppXX{} code relying on subsumption with \tcode{common_reference_with} may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} template requires @\libconcept{equality_comparable_with}@ @@ -422,6 +585,7 @@ return attempted_equals(p, nullptr); // ill-formed; previously well-formed } \end{codeblock} +\end{example} \rSec2[diff.cpp20.memory]{\ref{mem}: memory management library} @@ -452,11 +616,12 @@ contained errors in format strings or relied on previous format string signatures or \tcode{format_args_t} may become ill-formed. -For example: +\begin{example} \begin{codeblock} auto s = std::format("{:d}", "I am not a number"); // ill-formed, // previously threw \tcode{format_error} \end{codeblock} +\end{example} \diffref{format} \change @@ -469,7 +634,7 @@ \effect Valid \CppXX{} code that passes bit-fields to formatting functions may become ill-formed. -For example: +\begin{example} \begin{codeblock} struct tiny { int bit: 1; @@ -478,6 +643,7 @@ auto t = tiny(); std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"} \end{codeblock} +\end{example} \diffref{format.string.std} \change @@ -490,12 +656,13 @@ \effect Valid \CppXX{} code that passes a boolean or character type as \fmtgrammarterm{arg-id} becomes invalid. -For example: +\begin{example} \begin{codeblock} std::format("{:*^{}}", "", true); // ill-formed, previously returned \tcode{"*"} std::format("{:*^{}}", "", '1'); // ill-formed, previously returned an // implementation-defined number of \tcode{'*'} characters \end{codeblock} +\end{example} \diffref{format.formatter.spec} \change @@ -524,7 +691,7 @@ on an xvalue expression with type \tcode{S} that is a specialization of \tcode{basic_string} may change meaning in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} std::string s1 = "some long string that forces allocation", s2 = s1; std::move(s1).substr(10, 5); @@ -532,6 +699,7 @@ std::string s3(std::move(s2), 10, 5); assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true} \end{codeblock} +\end{example} \rSec2[diff.cpp20.containers]{\ref{containers}: containers library} @@ -543,7 +711,7 @@ Improve efficiency of erasing elements from associative containers. \effect Valid \CppXX{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct B { auto operator<=>(const B&) const = default; @@ -555,6 +723,7 @@ } }; \end{codeblock} +\end{example} \rSec2[diff.cpp20.thread]{\ref{thread}: concurrency support library} @@ -577,7 +746,7 @@ on a specific thread running the phase completion step, or on a completion function's side effects occurring without \tcode{wait} having been called. -For example: +\begin{example} \begin{codeblock} auto b0 = std::barrier(1); b0.arrive(); @@ -589,6 +758,7 @@ assert(data == 1); // implementation-defined; previously well-defined b1.arrive(); // implementation-defined; previously well-defined \end{codeblock} +\end{example} \rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}} @@ -597,7 +767,8 @@ \pnum \indextext{summary!compatibility with ISO \CppXVII{}}% Subclause \ref{diff.cpp17} lists the differences between \Cpp{} and -ISO \CppXVII{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppXVII{}, +in addition to those listed above, by the chapters of this document. \rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions} @@ -612,7 +783,7 @@ \tcode{module} or \tcode{import} may be interpreted differently in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} class module {}; module m1; // was variable declaration; now \grammarterm{module-declaration} @@ -622,6 +793,7 @@ import j1; // was variable declaration; now \grammarterm{module-import-declaration} ::import j2; // variable declaration \end{codeblock} +\end{example} \diffref{lex.header} \change @@ -632,12 +804,13 @@ When the identifier \tcode{import} is followed by a \tcode{<} character, a \grammarterm{header-name} token may be formed. -For example: +\begin{example} \begin{codeblock} template class import {}; import f(); // ill-formed; previously well-formed ::import g(); // OK \end{codeblock} +\end{example} \diffref{lex.key} \change @@ -685,7 +858,7 @@ Valid \CppXVII{} code that contains a \tcode{<=} token immediately followed by a \tcode{>} token may be ill-formed or have different semantics in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} namespace N { struct X {}; @@ -694,6 +867,7 @@ Y y; // ill-formed; previously well-formed } \end{codeblock} +\end{example} \diffref{lex.literal} \indextext{UTF-8}% @@ -708,7 +882,7 @@ UTF-8 string literals having type ``array of \tcode{const char}'' and UTF-8 character literals having type ``\tcode{char}'' is not valid in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} const auto *u8s = u8"text"; // \tcode{u8s} previously deduced as \tcode{const char*}; now deduced as \tcode{const char8_t*} const char *ps = u8s; // ill-formed; previously well-formed @@ -727,6 +901,7 @@ }; ct::type x; // ill-formed; previously well-formed. \end{codeblock} +\end{example} \rSec2[diff.cpp17.basic]{\ref{basic}: basics} @@ -739,7 +914,7 @@ \effect Valid ISO \CppXVII{} code may be ill-formed or have undefined behavior in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} int f() { int a = 123; @@ -748,6 +923,7 @@ return a; // undefined behavior; previously returned 123 } \end{codeblock} +\end{example} \diffref{intro.races} \change @@ -776,7 +952,7 @@ if those entities are only referenced in contexts that do not result in an odr-use. -\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl}: declarations} \diffref{dcl.typedef} \change @@ -786,12 +962,13 @@ Necessary for implementability. \effect Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} typedef struct { void f() {} // ill-formed; previously well-formed } S; \end{codeblock} +\end{example} \diffref{dcl.fct.default} \change @@ -802,7 +979,7 @@ \effect Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}, with no diagnostic required. -For example: +\begin{example} \begin{codeblock} // Translation unit 1 int f(int a = 42); @@ -813,6 +990,7 @@ int g(); int main() { return g(); } // used to return 42 \end{codeblock} +\end{example} \diffref{dcl.init.aggr} \change @@ -825,7 +1003,7 @@ a type with a user-declared constructor may be ill-formed or have different semantics in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct A { // not an aggregate; previously an aggregate A() = delete; @@ -858,6 +1036,7 @@ Y y{X{}}; // copy constructor call; previously aggregate-initialization \end{codeblock} +\end{example} \diffref{dcl.init.list} \change @@ -868,10 +1047,11 @@ \effect Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} bool y[] = { "bc" }; // ill-formed; previously well-formed \end{codeblock} +\end{example} \rSec2[diff.cpp17.class]{\ref{class}: classes} @@ -888,7 +1068,7 @@ \effect Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct S { explicit (S)(const S&); // ill-formed; previously well-formed @@ -896,6 +1076,7 @@ explicit(true) (S)(int); // OK }; \end{codeblock} +\end{example} \diffref{class.ctor,class.dtor} \change @@ -906,7 +1087,7 @@ \effect Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} template struct A { @@ -915,6 +1096,7 @@ ~A(); // error: \grammarterm{simple-template-id} not allowed for destructor }; \end{codeblock} +\end{example} \diffref{class.copy.elision} \change @@ -928,7 +1110,7 @@ \effect Valid \CppXVII{} code may fail to compile or have different semantics in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct base { base(); @@ -960,6 +1142,7 @@ char c = *s.m; // undefined behavior; previously ok } \end{codeblock} +\end{example} \rSec2[diff.cpp17.over]{\ref{over}: overloading} @@ -976,7 +1159,7 @@ and an object of the other type invoke a different operator. Also, for certain types, equality or inequality expressions between two objects of that type become ambiguous. -For example: +\begin{example} \begin{codeblock} struct A { operator int() const; @@ -992,6 +1175,7 @@ (10 != x); // calls \#1, previously selected \#3 } \end{codeblock} +\end{example} \diffref{over.match.oper} \change @@ -1001,7 +1185,7 @@ \effect Valid \CppXVII{} code that uses equality operators with conversion functions may be ill-formed or have different semantics in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct A { operator int() const { return 10; } @@ -1017,6 +1201,7 @@ B b1; bool eq = (b1 == b1); // ambiguous; previously well-formed \end{codeblock} +\end{example} \rSec2[diff.cpp17.temp]{\ref{temp}: templates} @@ -1038,7 +1223,7 @@ Previously valid code that uses a function name as the left operand of a \tcode{<} operator would become ill-formed. -For example: +\begin{example} \begin{codeblock} struct A {}; bool operator<(void (*fp)(), A); @@ -1049,6 +1234,7 @@ (f) < a; // still well-formed } \end{codeblock} +\end{example} \rSec2[diff.cpp17.except]{\ref{except}: exception handling} @@ -1178,13 +1364,14 @@ Increase safety via preventing buffer overflow at compile time. \effect Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} auto p = new char[100]; char q[100]; std::cin >> std::setw(20) >> p; // ill-formed; previously well-formed std::cin >> std::setw(20) >> q; // OK \end{codeblock} +\end{example} \diffref{ostream.inserters.character} \indextext{UTF-8}% @@ -1196,13 +1383,14 @@ Valid \CppXVII{} code that passes UTF-8 literals to \tcode{basic_ostream::operator<<} or \tcode{basic_ostream::operator<<} is now ill-formed. -For example: +\begin{example} \begin{codeblock} std::cout << u8"text"; // previously called \tcode{operator<<(const char*)} and printed a string; // now ill-formed std::cout << u8'X'; // previously called \tcode{operator<<(char)} and printed a character; // now ill-formed \end{codeblock} +\end{example} \diffref{ostream.inserters.character} \change @@ -1216,13 +1404,14 @@ to \tcode{basic_ostream::operator<<} or that passes \keyword{char16_t} or \keyword{char32_t} characters or strings to \tcode{basic_ostream::operator<<} is now ill-formed. -For example: +\begin{example} \begin{codeblock} std::cout << u"text"; // previously formatted the string as a pointer value; // now ill-formed std::cout << u'X'; // previously formatted the character as an integer value; // now ill-formed \end{codeblock} +\end{example} \diffref{fs.class.path} \change @@ -1233,12 +1422,13 @@ Valid \CppXVII{} code that depends on the \tcode{u8string()} and \tcode{generic_u8string()} member functions of \tcode{std::filesystem::path} returning \tcode{std::string} is not valid in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} std::filesystem::path p; std::string s1 = p.u8string(); // ill-formed; previously well-formed std::string s2 = p.generic_u8string(); // ill-formed; previously well-formed \end{codeblock} +\end{example} \rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features} @@ -1337,7 +1527,7 @@ \pnum \indextext{summary!compatibility with ISO \CppXIV{}}% Subclause \ref{diff.cpp14} lists the differences between \Cpp{} and -ISO \CppXIV{} (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppXIV{}, in addition to those listed above, by the chapters of this document. @@ -1353,8 +1543,9 @@ Valid \CppXIV{} code that uses trigraphs may not be valid or may have different semantics in this revision of \Cpp{}. Implementations may choose to translate trigraphs as specified in \CppXIV{} if they appear outside of a raw -string literal, as part of the \impldef{mapping input source file characters -to translation character set} mapping from input source file characters to +string literal, as part of the +\impldef{mapping input file characters to translation character set} +mapping from input source file characters to the translation character set. \diffref{lex.ppnumber} @@ -1368,11 +1559,12 @@ this revision of \Cpp{}. Specifically, character sequences like \tcode{0p+0} and \tcode{0e1_p+0} are three separate tokens each in \CppXIV{}, but one single token in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #define F(a) b ## a int b0p = F(0p+0); // ill-formed; equivalent to ``\tcode{int b0p = b0p + 0;}\!'' in \CppXIV{} \end{codeblock} +\end{example} \rSec2[diff.cpp14.expr]{\ref{expr}: expressions} @@ -1400,7 +1592,7 @@ \tcode{::operator new(std::size_t, std::align_val_t)} is used instead. -\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl}: declarations} \diffref{dcl.stc} \indextext{\idxcode{register} storage class}% @@ -1421,11 +1613,12 @@ \effect Valid \CppXIV{} code may fail to compile or may change meaning in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} auto x1{1}; // was \tcode{std::initializer_list}, now \tcode{int} auto x2{1, 2}; // was \tcode{std::initializer_list}, now ill-formed \end{codeblock} +\end{example} \diffref{dcl.fct} \change @@ -1435,13 +1628,14 @@ \effect Valid \CppXIV{} code may fail to compile or change meaning in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} void g1() noexcept; void g2(); template int f(T *, T *); int x = f(g1, g2); // ill-formed; previously well-formed \end{codeblock} +\end{example} \diffref{dcl.init.aggr} \change @@ -1454,7 +1648,7 @@ revision of \Cpp{}; initialization from an empty initializer list will perform aggregate initialization instead of invoking a default constructor for the affected types. -For example: +\begin{example} \begin{codeblock} struct derived; struct base { @@ -1467,6 +1661,7 @@ derived d1{}; // error; the code was well-formed in \CppXIV{} derived d2; // still OK \end{codeblock} +\end{example} \rSec2[diff.cpp14.class]{\ref{class}: classes} @@ -1481,7 +1676,7 @@ that names a constructor now makes the corresponding base class constructors visible to initializations of the derived class rather than declaring additional derived class constructors. -For example: +\begin{example} \begin{codeblock} struct A { template A(T, typename T::type = 0); @@ -1495,21 +1690,22 @@ // which called \tcode{A(int)} due to substitution failure // in \tcode{A(long)}. \end{codeblock} +\end{example} \rSec2[diff.cpp14.temp]{\ref{temp}: templates} \diffref{temp.deduct.type} \change -Allowance to deduce from the type of a non-type template argument. +Allowance to deduce from the type of a constant template argument. \rationale In combination with the ability to declare -non-type template arguments with placeholder types, +constant template arguments with placeholder types, allows partial specializations to decompose -from the type deduced for the non-type template argument. +from the type deduced for the constant template argument. \effect Valid \CppXIV{} code may fail to compile or produce different results in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} template struct A; template int foo(A *) = delete; @@ -1518,6 +1714,7 @@ foo(p); // ill-formed; previously well-formed } \end{codeblock} +\end{example} \rSec2[diff.cpp14.except]{\ref{except}: exception handling} @@ -1598,12 +1795,13 @@ \effect Valid \CppXIV{} code may fail to compile or may change meaning in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #include std::unique_ptr arr(new int[1]); std::shared_ptr ptr(std::move(arr)); // error: \tcode{int(*)[]} is not compatible with \tcode{int*} \end{codeblock} +\end{example} \rSec2[diff.cpp14.string]{\ref{strings}: strings library} @@ -1620,13 +1818,14 @@ will execute differently when called with a non-const string's \tcode{.data()} member in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} int f(char *) = delete; int f(const char *); string s; int x = f(s.data()); // ill-formed; previously well-formed \end{codeblock} +\end{example} \rSec2[diff.cpp14.containers]{\ref{containers}: containers library} @@ -1639,7 +1838,7 @@ Valid \CppXIV{} code that attempts to use associative containers having a comparison object with non-const function call operator may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #include @@ -1656,6 +1855,7 @@ s.find(0); } \end{codeblock} +\end{example} \rSec2[diff.cpp14.depr]{\ref{depr}: compatibility features} @@ -1697,7 +1897,7 @@ \pnum \indextext{summary!compatibility with ISO \CppXI{}}% Subclause \ref{diff.cpp11} lists the differences between \Cpp{} and -ISO \CppXI{} (ISO/IEC 14882:2011, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppXI{}, in addition to those listed above, by the chapters of this document. @@ -1714,13 +1914,14 @@ this revision of \Cpp{}, but the macro invocation produces different outcomes because the single quotes delimit a \grammarterm{character-literal} in \CppXI{}, whereas they are digit separators in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #define M(x, ...) __VA_ARGS__ int x[2] = { M(1'2,3'4, 5) }; // \tcode{int x[2] = \{ 5 \};\ \ \ \ \ } --- \CppXI{} // \tcode{int x[2] = \{ 3'4, 5 \};} --- this revision of \Cpp{} \end{codeblock} +\end{example} \rSec2[diff.cpp11.basic]{\ref{basic}: basics} @@ -1756,7 +1957,7 @@ \effect Valid \CppXI{} code that relies on the conversions may behave differently in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct S { int x = 1; @@ -1775,8 +1976,9 @@ \end{codeblock} In \CppXI{}, the expression yields \tcode{sizeof(const char*)}. In this revision of \Cpp{}, it yields \tcode{sizeof(const char[1])}. +\end{example} -\rSec2[diff.cpp11.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp11.dcl.dcl]{\ref{dcl}: declarations} \diffref{dcl.constexpr} \change @@ -1787,7 +1989,7 @@ the object. \effect Valid \CppXI{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct S { constexpr const int &f(); @@ -1797,6 +1999,7 @@ This code is valid in \CppXI{} but invalid in this revision of \Cpp{} because it declares the same member function twice with different return types. +\end{example} \diffref{dcl.init.aggr} \change @@ -1806,7 +2009,7 @@ by aggregate initialization. \effect Valid \CppXI{} code may fail to compile or may change meaning in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} struct S { // Aggregate in \CppXIV{} onwards. int m = 1; @@ -1819,6 +2022,7 @@ S b{a}; // uses copy constructor in \CppXI{}, // performs aggregate initialization in this revision of \Cpp{} \end{codeblock} +\end{example} \rSec2[diff.cpp11.library]{\ref{library}: library introduction} @@ -1850,7 +2054,7 @@ \pnum \indextext{summary!compatibility with ISO \CppIII{}}% Subclause \ref{diff.cpp03} lists the differences between \Cpp{} and -ISO \CppIII{} (ISO/IEC 14882:2003, \doccite{Programming Languages --- \Cpp{}}), +ISO \CppIII{}, in addition to those listed above, by the chapters of this document. @@ -1867,11 +2071,12 @@ \tcode{u8R}, \tcode{u}, \tcode{uR}, \tcode{U}, \tcode{UR}, or \tcode{LR} will not be expanded when adjacent to a \grammarterm{string-literal} but will be interpreted as part of the \grammarterm{string-literal}. -For example: +\begin{example} \begin{codeblock} #define u8 "abc" const char* s = u8"def"; // Previously \tcode{"abcdef"}, now \tcode{"def"} \end{codeblock} +\end{example} \diffref{lex.pptoken} \change @@ -1881,7 +2086,7 @@ \effect Valid \CppIII{} code may fail to compile or produce different results in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #define _x "there" "hello"_x // \#1 @@ -1890,6 +2095,7 @@ Previously, \#1 would have consisted of two separate preprocessing tokens and the macro \tcode{_x} would have been expanded. In this revision of \Cpp{}, \#1 consists of a single preprocessing token, so the macro is not expanded. +\end{example} \diffref{lex.key} \change @@ -1931,7 +2137,7 @@ \effect Valid \CppIII{} code may fail to compile or produce different results in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} void f(void *); // \#1 void f(...); // \#2 @@ -1939,6 +2145,29 @@ f(0*N); // calls \#2; used to call \#1 } \end{codeblock} +\end{example} + +\diffref{expr.typeid} +\change +Evaluation of operands in \keyword{typeid}. +\rationale +Introduce additional expression value categories. +\effect +Valid \CppIII{} code that uses xvalues as operands for \keyword{typeid} +may change behavior in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + struct B { + B() {} + virtual ~B() { } + }; + + struct C { B b; }; + typeid(C().b); // unevaluated in \CppIII{}, evaluated in \CppXI{} +} +\end{codeblock} +\end{example} \diffref{expr.mul} \change @@ -1958,14 +2187,40 @@ \effect Valid \CppIII{} code may fail to compile or produce different results in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} bool b1 = new int && false; // previously \tcode{false}, now ill-formed struct S { operator int(); }; bool b2 = &S::operator int && false; // previously \tcode{false}, now ill-formed \end{codeblock} +\end{example} -\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl.dcl}: declarations} +\diffref{expr.cond} +\change +Fewer copies in the conditional operator. +\rationale +Introduce additional expression value categories. +\effect +Valid \CppIII{} code that uses xvalues as operands for the conditional operator +may change behavior in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + struct B { + B() {} + B(const B&) { } + }; + struct D : B {}; + + struct BB { B b; }; + struct DD { D d; }; + + true ? BB().b : DD().d; // additional copy in \CppIII{}, no copy or move in \CppXI{} +} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl}: declarations} \diffref{dcl.spec} \change @@ -1987,13 +2242,14 @@ Catches bugs. \effect Valid \CppIII{} code may fail to compile in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} int x[] = { 2.0 }; \end{codeblock} This code is valid in \CppIII{} but invalid in this revision of \Cpp{} because \tcode{double} to \tcode{int} is a narrowing conversion. +\end{example} \diffref{dcl.link} \change @@ -2005,7 +2261,7 @@ \effect Valid \CppIII{} code may violate the one-definition rule\iref{basic.def.odr} in this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} namespace { extern "C" { extern int x; } } // \#1, previously external linkage and C language linkage, // now internal linkage and \Cpp{} language linkage @@ -2015,6 +2271,7 @@ This code is valid in \CppIII{}, but \tcode{\#2} is not a definition for \tcode{\#1} in this revision of \Cpp{}, violating the one-definition rule. +\end{example} \rSec2[diff.cpp03.class]{\ref{class}: classes} @@ -2062,7 +2319,7 @@ Change to semantics of well-defined expression. A valid \CppIII{} expression containing a right angle bracket (``\tcode{>}'') followed immediately by another right angle bracket may now be treated as closing two templates. -For example: +\begin{example} \begin{codeblock} template struct X { }; template struct Y { }; @@ -2071,6 +2328,7 @@ This code is valid in \CppIII{} because ``\tcode{>>}'' is a right-shift operator, but invalid in this revision of \Cpp{} because ``\tcode{>>}'' closes two templates. +\end{example} \diffref{temp.dep.candidate} \change @@ -2109,7 +2367,7 @@ \libheaderrefx{condition_variable}{condition.variable.syn}, \libheaderrefx{forward_list}{forward.list.syn}, \libheaderref{future}, -\libheaderrefx{initiali\-zer_list}{initializer.list.syn}, +\libheaderrefxx{initializer_list}{initiali\-zer_list}{initializer.list.syn}, \libheaderref{mutex}, \libheaderrefx{random}{rand.synopsis}, \libheaderref{ratio}, @@ -2118,7 +2376,7 @@ \libheaderrefx{system_error}{system.error.syn}, \libheaderref{thread}, \libheaderref{tuple}, -\libheaderrefx{type\-index}{type.index.synopsis}, +\libheaderrefxx{typeindex}{type\-index}{type.index.synopsis}, \libheaderrefx{type_traits}{meta.type.synop}, \libheaderrefx{unordered_map}{unord.map.syn}, and @@ -2133,12 +2391,12 @@ invalid in this revision of \Cpp{}. \diffref{swappable.requirements} -\effect -Function \tcode{swap} moved to a different header +\change +Function \tcode{swap} moved to a different header. \rationale Remove dependency on \libheaderref{algorithm} for \tcode{swap}. \effect -Valid \CppIII{} code that has been compiled expecting swap to be in +Valid \CppIII{} code that has been compiled expecting \tcode{swap} to be in \libheaderref{algorithm} may have to instead include \libheaderref{utility}. \diffref{namespace.posix} @@ -2151,15 +2409,15 @@ \CppIII{} code that uses a top-level namespace \tcode{posix} may be invalid in this revision of \Cpp{}. -\diffref{res.on.macro.definitions} +\diffref{macro.names} \change Additional restrictions on macro names. \rationale Avoid hard to diagnose or non-portable constructs. \effect Names of attribute identifiers may not be used as macro names. Valid \CppIII{} -code that defines \tcode{override}, \tcode{final}, -\tcode{carries_dependency}, or \tcode{noreturn} as macros is invalid in this +code that defines \tcode{override}, \tcode{final}, or +\tcode{noreturn} as macros is invalid in this revision of \Cpp{}. \rSec2[diff.cpp03.language.support]{\ref{support}: @@ -2397,7 +2655,7 @@ Valid \CppIII{} code that relies on \tcode{std::ios_base} flag types being represented as \tcode{std::bitset} or as an integer type may fail to compile with this revision of \Cpp{}. -For example: +\begin{example} \begin{codeblock} #include @@ -2406,14 +2664,15 @@ std::cout.setf(flag); // error: \tcode{setf} does not take argument of type \tcode{int} } \end{codeblock} +\end{example} -\rSec1[diff.iso]{\Cpp{} and ISO C} +\rSec1[diff.iso]{\Cpp{} and C} \rSec2[diff.iso.general]{General} \pnum -\indextext{summary!compatibility with ISO C}% -Subclause \ref{diff.iso} lists the differences between \Cpp{} and ISO C, +\indextext{summary!compatibility with C}% +Subclause \ref{diff.iso} lists the differences between \Cpp{} and C, in addition to those listed above, by the chapters of this document. @@ -2421,7 +2680,7 @@ \diffref{lex.key} \change -New Keywords\\ +New Keywords.\\ New keywords are added to \Cpp{}; see \ref{lex.key}. \rationale @@ -2429,7 +2688,7 @@ semantics of \Cpp{}. \effect Change to semantics of well-defined feature. -Any ISO C programs that used any of these keywords as identifiers +Any C programs that used any of these keywords as identifiers are not valid \Cpp{} programs. \difficulty Syntactic transformation. @@ -2444,7 +2703,8 @@ Type of \grammarterm{character-literal} is changed from \tcode{int} to \tcode{char}. \rationale This is needed for improved overloaded function argument type -matching. For example: +matching. +\begin{example} \begin{codeblock} int function( int i ); int function( char c ); @@ -2453,9 +2713,10 @@ \end{codeblock} It is preferable that this call match the second version of function rather than the first. +\end{example} \effect Change to semantics of well-defined feature. -ISO C programs which depend on +C programs which depend on \begin{codeblock} sizeof('x') == sizeof(int) \end{codeblock} @@ -2525,16 +2786,18 @@ \diffref{basic.def} \change \Cpp{} does not have ``tentative definitions'' as in C.\\ -E.g., at file scope, +\begin{example} +At file scope, \begin{codeblock} int i; int i; \end{codeblock} is valid in C, invalid in \Cpp{}. +\end{example} This makes it impossible to define mutually referential file-local objects with static storage duration, if initializers are restricted to the syntactic forms of C\@. -For example, +\begin{example} \begin{codeblock} struct X { int i; struct X* next; }; @@ -2542,6 +2805,7 @@ static struct X b = { 0, &a }; static struct X a = { 1, &b }; \end{codeblock} +\end{example} \rationale This avoids having different initialization rules for fundamental types and user-defined types. @@ -2559,7 +2823,7 @@ \diffref{basic.scope} \change A \keyword{struct} is a scope in \Cpp{}, not in C. -For example, +\begin{example} \begin{codeblock} struct X { struct Y { int a; } b; @@ -2567,6 +2831,7 @@ struct Y c; \end{codeblock} is valid in C but not in \Cpp{}, which would require \tcode{X::Y c;}. +\end{example} \rationale Class scope is crucial to \Cpp{}, and a struct is a class. \effect @@ -2636,6 +2901,7 @@ \diffref{conv.ptr} \change Converting \tcode{\keyword{void}*} to a pointer-to-object type requires casting. +\begin{example} \begin{codeblock} char a[10]; void* b=a; @@ -2644,9 +2910,10 @@ } \end{codeblock} -ISO C accepts this usage of pointer to \keyword{void} being assigned +C accepts this usage of pointer to \keyword{void} being assigned to a pointer to object type. \Cpp{} does not. +\end{example} \rationale \Cpp{} tries harder than C to enforce compile-time type safety. \effect @@ -2654,24 +2921,24 @@ \difficulty Can be automated. Violations will be diagnosed by the \Cpp{} translator. -The -fix is to add a cast. -For example: +The fix is to add a cast. +\begin{example} \begin{codeblock} char* c = (char*) b; \end{codeblock} +\end{example} \howwide This is fairly widely used but it is good programming practice to add the cast when assigning pointer-to-void to pointer-to-object. -Some ISO C translators will give a warning +Some C translators will give a warning if the cast is not used. \diffref{expr.arith.conv} \change Operations mixing a value of an enumeration type and a value of a different enumeration type or of a floating-point type are not valid. -For example: +\begin{example} \begin{codeblock} enum E1 { e }; enum E2 { f }; @@ -2679,6 +2946,7 @@ int k = f - e; // valid in C; ill-formed in \Cpp{} int x = 1 ? e : f; // valid in C; ill-formed in \Cpp{} \end{codeblock} +\end{example} \rationale Reinforcing type safety in \Cpp{}. \effect @@ -2686,13 +2954,14 @@ \difficulty Violations will be diagnosed by the \Cpp{} translator. The original behavior can be restored with a cast or integral promotion. -For example: +\begin{example} \begin{codeblock} enum E1 { e }; enum E2 { f }; int b = (int)e <= 3.7; int k = +f - e; \end{codeblock} +\end{example} \howwide Uncommon. @@ -2702,7 +2971,7 @@ \rationale Feature with surprising semantics. \effect -A valid ISO C expression utilizing the decrement operator on +A valid C expression utilizing the decrement operator on a \keyword{bool} lvalue (for instance, via the C typedef in \libheaderref{stdbool.h}) is ill-formed in \Cpp{}. @@ -2711,11 +2980,12 @@ \change In \Cpp{}, types can only be defined in declarations, not in expressions.\\ In C, a \keyword{sizeof} expression or cast expression may define a new type. -For example, +\begin{example} \begin{codeblock} p = (void*)(struct x {int i;} *)0; \end{codeblock} defines a new type, struct \tcode{x}. +\end{example} \rationale This prohibition helps to clarify the location of definitions in the source code. @@ -2726,7 +2996,31 @@ \howwide Seldom. -\diffref{expr.cond,expr.ass,expr.comma} +\diffref{expr.rel,expr.eq} +\change +C allows directly comparing two objects of array type; \Cpp{} does not. +\rationale +The behavior is confusing because it compares not the contents of the two +arrays, but their addresses. +\effect +Deletion of semantically well-defined feature that had unspecified behavior +in common use cases. +\difficulty +Violations will be diagnosed by the \Cpp{} translator. The original behavior +can be replicated by explicitly casting either array to a pointer, such as by +using a unary \tcode{+}. +\begin{example} +\begin{codeblock} +int arr1[5]; +int arr2[5]; +int same = arr1 == arr2; // valid C, ill-formed C++ +int idem = arr1 == +arr2; // valid in both C and C++ +\end{codeblock} +\end{example} +\howwide +Rare. + +\diffref{expr.cond,expr.assign,expr.comma} \indextext{conversion!lvalue-to-rvalue}% \indextext{rvalue!lvalue conversion to}% \indextext{lvalue}% @@ -2740,7 +3034,7 @@ Change to semantics of well-defined feature. Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results. -For example, +\begin{example} \begin{codeblock} char arr[100]; sizeof(0, arr) @@ -2750,12 +3044,13 @@ in \Cpp{} and \tcode{sizeof(char*)} in C. +\end{example} \difficulty Programs must add explicit casts to the appropriate rvalue. \howwide Rare. -\rSec2[diff.stat]{\ref{stmt.stmt}: statements} +\rSec2[diff.stat]{\ref{stmt}: statements} \diffref{stmt.switch,stmt.goto} \change @@ -2803,7 +3098,7 @@ For several years, many existing C implementations have produced warnings in this case. -\rSec2[diff.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.dcl]{\ref{dcl}: declarations} \diffref{dcl.stc} \change @@ -2811,12 +3106,13 @@ Using these specifiers with type declarations is illegal in \Cpp{}. In C, these specifiers are ignored when used on type declarations. -Example: +\begin{example} \begin{codeblock} static struct S { // valid C, invalid in \Cpp{} int i; }; \end{codeblock} +\end{example} \rationale Storage class specifiers don't have any meaning when associated @@ -2851,23 +3147,25 @@ same name). In C, a \grammarterm{typedef-name} and a struct tag name declared in the same scope can have the same name (because they have different name spaces). -Example: +\begin{example} \begin{codeblock} typedef struct name1 { @\commentellip@ } name1; // valid C and \Cpp{} struct name { @\commentellip@ }; typedef int name; // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale For ease of use, \Cpp{} doesn't require that a type name be prefixed with the keywords \keyword{class}, \keyword{struct} or \keyword{union} when used in object declarations or type casts. -Example: +\begin{example} \begin{codeblock} class name { @\commentellip@ }; name i; // \tcode{i} has type \tcode{class name} \end{codeblock} +\end{example} \effect Deletion of semantically well-defined feature. @@ -2894,12 +3192,13 @@ \change The keyword \keyword{auto} cannot be used as a storage class specifier. -Example: +\begin{example} \begin{codeblock} void f() { auto int x; // valid C, invalid \Cpp{} } \end{codeblock} +\end{example} \rationale Allowing the use of \keyword{auto} to deduce the type @@ -2917,11 +3216,12 @@ In \Cpp{}, a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown. -Example: +\begin{example} \begin{codeblock} int f(); // means \tcode{int f(void)} in \Cpp{} // \tcode{int f(} unknown \tcode{)} in C \end{codeblock} +\end{example} \rationale This is to avoid function calls @@ -2944,11 +3244,12 @@ In \Cpp{}, types may not be defined in return or parameter types. In C, these type definitions are allowed. -Example: +\begin{example} \begin{codeblock} void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp{} enum E { A, B, C } f() {} // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale When comparing types in different translation units, \Cpp{} relies @@ -2991,7 +3292,7 @@ designated and non-designated initializers cannot be mixed in the same initializer list. -Example: +\begin{example} \begin{codeblock} struct A { int x, y; }; struct B { struct A a; }; @@ -3000,6 +3301,7 @@ struct B b = {.a.x = 0}; // valid C, invalid \Cpp{} struct A c = {.x = 1, 2}; // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale In \Cpp{}, members are destroyed in reverse construction order and the elements of an initializer list are evaluated in lexical order, @@ -3021,10 +3323,11 @@ number of elements in the array. In C, an array can be initialized with a string even if the array is not large enough to contain the string-terminating \tcode{'\textbackslash 0'}. -Example: +\begin{example} \begin{codeblock} char array[4] = "abcd"; // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale When these non-terminated arrays are manipulated by standard string functions, there is potential for major catastrophe. @@ -3043,11 +3346,12 @@ \Cpp{} objects of enumeration type can only be assigned values of the same enumeration type. In C, objects of enumeration type can be assigned values of any integral type. -Example: +\begin{example} \begin{codeblock} enum color { red, blue, green }; enum color c = 1; // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale The type-safe nature of \Cpp{}. @@ -3064,13 +3368,14 @@ \change In \Cpp{}, the type of an enumerator is its enumeration. In C, the type of an enumerator is \keyword{int}. -Example: +\begin{example} \begin{codeblock} enum e { A }; sizeof(A) == sizeof(int) // in C sizeof(A) == sizeof(e) // in \Cpp{} /* and @sizeof(int)@ is not necessarily equal to @sizeof(e)@ */ \end{codeblock} +\end{example} \rationale In \Cpp{}, an enumeration is a distinct type. @@ -3091,12 +3396,14 @@ an \grammarterm{alignment-specifier} is an \grammarterm{attribute-specifier}. In C, an \grammarterm{alignment-specifier} is a \gterm{declaration-specifier}. -Example: +\begin{example} \begin{codeblock} #include unsigned alignas(8) int x; // valid C, invalid \Cpp{} unsigned int y alignas(8); // valid \Cpp{}, invalid C \end{codeblock} +\end{example} + \rationale \Cpp{} requires unambiguous placement of the \grammarterm{alignment-specifier}. \effect @@ -3115,7 +3422,7 @@ scope. In C, an inner scope declaration of a struct tag name never hides the name of an object or function in an outer scope. -Example: +\begin{example} \begin{codeblock} int x[99]; void f() { @@ -3124,6 +3431,7 @@ /* size of the struct in @\textit{\textrm{\Cpp{}}}@ */ } \end{codeblock} +\end{example} \rationale This is one of the few incompatibilities between C and \Cpp{} that can be attributed to the new \Cpp{} name space definition where a @@ -3154,7 +3462,8 @@ The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a copy of a volatile lvalue. -For example, the following is valid in ISO C: +\begin{example} +The following is valid in C: \begin{codeblock} struct X { int i; }; volatile struct X x1 = {0}; @@ -3162,6 +3471,7 @@ struct X x3; x3 = x1; // also invalid \Cpp{} \end{codeblock} +\end{example} \rationale Several alternatives were debated at length. @@ -3214,13 +3524,14 @@ In \Cpp{}, the name of a nested class is local to its enclosing class. In C the name of the nested class belongs to the same scope as the name of the outermost enclosing class. -Example: +\begin{example} \begin{codeblock} struct X { struct Y { @\commentellip@ } y; }; struct Y yy; // valid C, invalid \Cpp{} \end{codeblock} +\end{example} \rationale \Cpp{} classes have member functions which require that classes establish scopes. @@ -3238,13 +3549,14 @@ To make the struct type name visible in the scope of the enclosing struct, the struct tag can be declared in the scope of the enclosing struct, before the enclosing struct is defined. -Example: +\begin{example} \begin{codeblock} struct Y; // \tcode{struct Y} and \tcode{struct X} are at the same scope struct X { struct Y { @\commentellip@ } y; }; \end{codeblock} +\end{example} All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of the enclosing @@ -3258,7 +3570,7 @@ \change In \Cpp{}, a \grammarterm{typedef-name} may not be redeclared in a class definition after being used in that definition. -Example: +\begin{example} \begin{codeblock} typedef int I; struct S { @@ -3266,6 +3578,7 @@ int I; // valid C, invalid \Cpp{} }; \end{codeblock} +\end{example} \rationale When classes become complicated, allowing such a redefinition after the type has been used can create confusion for \Cpp{} @@ -3285,7 +3598,7 @@ Whether \mname{STDC} is defined and if so, what its value is, are \impldef{definition and meaning of \mname{STDC}}. \rationale -\Cpp{} is not identical to ISO C\@. +\Cpp{} is not identical to C\@. Mandating that \mname{STDC} be defined would require that translators make an incorrect claim. \effect @@ -3379,7 +3692,6 @@ by \libheaderref{iso646.h}. \rSec3[diff.header.stdalign.h]{Header \tcode{}} -\indexhdr{stdalign.h}% \pnum The token \keyword{alignas} is a keyword in \Cpp{}\iref{lex.key}, @@ -3387,7 +3699,6 @@ by \libheaderref{stdalign.h}. \rSec3[diff.header.stdbool.h]{Header \tcode{}} -\indexhdr{stdbool.h}% \pnum The tokens \keyword{bool}, \keyword{true}, and \keyword{false} diff --git a/source/concepts.tex b/source/concepts.tex index 0508cb542b..4d848e8fd6 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -420,7 +420,7 @@ let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that \tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. \tcode{T} and \tcode{U} model \tcode{\libconcept{common_reference_with}} -only if: +only if \begin{itemize} \item \tcode{C(t1)} equals \tcode{C(t2)} if and only if \tcode{t1} equals \tcode{t2}, and @@ -473,7 +473,7 @@ let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that \tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. \tcode{T} and \tcode{U} model \tcode{\libconcept{common_with}} -only if: +only if \begin{itemize} \item \tcode{C(t1)} equals \tcode{C(t2)} if and only if \tcode{t1} equals \tcode{t2}, and @@ -881,7 +881,7 @@ \pnum Let \tcode{e} be an expression such that \tcode{decltype((e))} is \tcode{T}. -\tcode{T} models \exposconcept{boolean-testable-impl} only if: +\tcode{T} models \exposconcept{boolean-testable-impl} only if \begin{itemize} \item @@ -1024,7 +1024,7 @@ let \tcode{u1} and \tcode{u2} be equality-preserving expressions that are lvalues of type \tcode{remove_cvref_t}. \tcode{T} and \tcode{U} model -\tcode{\exposconcept{comparison-common-type-with}} only if: +\tcode{\exposconcept{comparison-common-type-with}} only if \begin{itemize} \item \tcode{\exposid{CONVERT_TO_LVALUE}(t1)} equals @@ -1222,7 +1222,7 @@ \rSec2[concepts.callable.general]{General} \pnum -The concepts in subclause \ref{concepts.callable} describe the requirements on function +The concepts in \ref{concepts.callable} describe the requirements on function objects\iref{function.objects} and their arguments. \rSec2[concept.invocable]{Concept \cname{invocable}} diff --git a/source/config.tex b/source/config.tex index be1743a556..3937ed3116 100644 --- a/source/config.tex +++ b/source/config.tex @@ -2,12 +2,15 @@ %%-------------------------------------------------- %% Version numbers \newcommand{\docno}{Dxxxx} -\newcommand{\prevdocno}{N4981} +\newcommand{\prevdocno}{N5008} \newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} +%% Core chapters +\newcommand{\lastcorechapter}{cpp} + %% Library chapters \newcommand{\firstlibchapter}{support} -\newcommand{\lastlibchapter}{thread} +\newcommand{\lastlibchapter}{exec} diff --git a/source/containers.tex b/source/containers.tex index c2d1113887..ba5e29341c 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -20,7 +20,8 @@ \ref{container.requirements} & Requirements & \\ \rowsep \ref{sequences} & Sequence containers & \tcode{}, \tcode{}, \tcode{}, - \tcode{}, \tcode{} \\ \rowsep + \tcode{}, \\ & & + \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{associative} & Associative containers & \tcode{}, \tcode{} \\ \rowsep \ref{unord} & Unordered associative containers & @@ -74,7 +75,7 @@ \rSec3[container.intro.reqmts]{Introduction} \pnum -In subclause \ref{container.requirements.general}, +In \ref{container.requirements.general}, \begin{itemize} \item \tcode{X} denotes a container class containing objects of type \tcode{T}, @@ -111,6 +112,7 @@ \indexlibrarymemberx{array}{#1}% \indexlibrarymemberx{deque}{#1}% \indexlibrarymemberx{forward_list}{#1}% +\indexlibrarymemberx{hive}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% \indexlibrarymemberx{map}{#1}% @@ -121,6 +123,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 @@ -262,7 +268,7 @@ \pnum \complexity -Linear for \tcode{array} and constant for all other standard containers. +Linear for \tcode{array} and \tcode{inplace_vector} and constant for all other standard containers. \end{itemdescr} \indexcont{operator=}% @@ -421,7 +427,25 @@ Constant. \end{itemdescr} -\indexcont{operator==}% +% hive is excluded here +\indexlibrarymisc{\idxcode{operator==}}{containers}% +\indexlibrarymemberx{array}{operator==}% +\indexlibrarymemberx{deque}{operator==}% +\indexlibrarymemberx{forward_list}{operator==}% +\indexlibrarymemberx{list}{operator==}% +\indexlibrarymemberx{vector}{operator==}% +\indexlibrarymemberx{map}{operator==}% +\indexlibrarymemberx{set}{operator==}% +\indexlibrarymemberx{multiset}{operator==}% +\indexlibrarymemberx{multimap}{operator==}% +\indexlibrarymemberx{unordered_map}{operator==}% +\indexlibrarymemberx{unordered_set}{operator==}% +\indexlibrarymemberx{unordered_multiset}{operator==}% +\indexlibrarymemberx{unordered_multimap}{operator==}% +\indexlibrarymemberx{flat_map}{operator==}% +\indexlibrarymemberx{flat_set}{operator==}% +\indexlibrarymemberx{flat_multiset}{operator==}% +\indexlibrarymemberx{flat_multimap}{operator==}% \begin{itemdecl} c == b \end{itemdecl} @@ -452,7 +476,25 @@ \tcode{==} is an equivalence relation. \end{itemdescr} -\indexcont{operator"!=}% +% hive is excluded here +\indexlibrarymisc{\idxcode{operator"!=}}{containers}% +\indexlibrarymemberx{array}{operator"!=}% +\indexlibrarymemberx{deque}{operator"!=}% +\indexlibrarymemberx{forward_list}{operator"!=}% +\indexlibrarymemberx{list}{operator"!=}% +\indexlibrarymemberx{vector}{operator"!=}% +\indexlibrarymemberx{map}{operator"!=}% +\indexlibrarymemberx{set}{operator"!=}% +\indexlibrarymemberx{multiset}{operator"!=}% +\indexlibrarymemberx{multimap}{operator"!=}% +\indexlibrarymemberx{unordered_map}{operator"!=}% +\indexlibrarymemberx{unordered_set}{operator"!=}% +\indexlibrarymemberx{unordered_multiset}{operator"!=}% +\indexlibrarymemberx{unordered_multimap}{operator"!=}% +\indexlibrarymemberx{flat_map}{operator"!=}% +\indexlibrarymemberx{flat_set}{operator"!=}% +\indexlibrarymemberx{flat_multiset}{operator"!=}% +\indexlibrarymemberx{flat_multimap}{operator"!=}% \begin{itemdecl} c != b \end{itemdecl} @@ -479,7 +521,8 @@ \pnum \complexity -Linear for \tcode{array} and constant for all other standard containers. +Linear for \tcode{array} and \tcode{inplace_vector}, and +constant for all other standard containers. \end{itemdescr} \begin{itemdecl} @@ -617,7 +660,8 @@ \pnum The expression \tcode{a.swap(b)}, for containers \tcode{a} and \tcode{b} of a standard -container type other than \tcode{array}, shall exchange the values of \tcode{a} and +container type other than \tcode{array} and \tcode{inplace_vector}, +shall exchange the values of \tcode{a} and \tcode{b} without invoking any move, copy, or swap operations on the individual container elements. Any \tcode{Compare}, \tcode{Pred}, or \tcode{Hash} types @@ -637,7 +681,7 @@ swap. \pnum -Unless otherwise specified (see~\ref{associative.reqmts.except}, \ref{unord.req.except}, \ref{deque.modifiers}, and +Unless otherwise specified (see~\ref{associative.reqmts.except}, \ref{unord.req.except}, \ref{deque.modifiers}, \ref{inplace.vector.modifiers}, and \ref{vector.modifiers}) all container types defined in this Clause meet the following additional requirements: @@ -720,6 +764,7 @@ \indexlibrarymisc{\idxcode{#1}}{reversible containers}% \indexlibrarymemberx{array}{#1}% \indexlibrarymemberx{deque}{#1}% +\indexlibrarymemberx{hive}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% \indexlibrarymemberx{map}{#1}% @@ -730,6 +775,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 @@ -908,7 +957,8 @@ \rSec3[container.alloc.reqmts]{Allocator-aware containers} \pnum -Except for \tcode{array}, all of the containers defined in \ref{containers}, +Except for \tcode{array} and \tcode{inplace_vector}, +all of the containers defined in \ref{containers}, \ref{stacktrace.basic}, \ref{basic.string}, and \ref{re.results} meet the additional requirements of an \defnadj{allocator-aware}{container}, as described below. @@ -1026,6 +1076,7 @@ \indexlibrarymisc{\idxcode{#1}}{allocator-aware containers}% \indexlibrarymemberx{deque}{#1}% \indexlibrarymemberx{forward_list}{#1}% +\indexlibrarymemberx{hive}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% \indexlibrarymemberx{map}{#1}% @@ -1117,7 +1168,7 @@ \pnum \ensures -\tcode{u == t}, \tcode{u.get_allocator() == m} +\tcode{u == t}, \tcode{u.get_allocator() == m}. \pnum \complexity @@ -1263,10 +1314,15 @@ \pnum A sequence container organizes a finite set of objects, all of the same type, into a strictly -linear arrangement. The library provides four basic kinds of sequence containers: -\tcode{vector}, \tcode{forward_list}, \tcode{list}, and \tcode{deque}. In addition, -\tcode{array} is provided as a sequence container which provides limited sequence operations -because it has a fixed number of elements. The library also provides container adaptors that +linear arrangement. The library provides the following basic kinds of sequence containers: +\tcode{vector}, \tcode{inplace_vector}, +\tcode{forward_list}, \tcode{list}, and \tcode{deque}. +In addition, +\tcode{array} and \tcode{hive} are provided as sequence containers +which provide limited sequence operations, +in \tcode{array}'s case because it has a fixed number of elements, and +in \tcode{hive}'s case because insertion order is unspecified. +The library also provides container adaptors that make it easy to construct abstract data types, such as \tcode{stack}s, \tcode{queue}s, @@ -1295,7 +1351,7 @@ denote iterators that meet the \oldconcept{InputIterator} requirements and refer to elements implicitly convertible to \tcode{value_type}, \item -\tcode{[i, j)} denotes a valid range, +\range{i}{j} denotes a valid range, \item \tcode{rg} denotes a value of a type \tcode{R} that models \tcode{\exposconcept{container-compatible-range}}, @@ -1308,7 +1364,7 @@ \item \tcode{q} denotes a valid dereferenceable constant iterator to \tcode{a}, \item -\tcode{[q1, q2)} denotes a valid range of constant iterators in \tcode{a}, +\range{q1}{q2} denotes a valid range of constant iterators in \tcode{a}, \item \tcode{t} denotes an lvalue or a const rvalue of \tcode{X::value_type}, and \item @@ -1370,7 +1426,7 @@ \pnum \effects -Constructs a sequence container equal to the range \tcode{[i, j)}. +Constructs a sequence container equal to the range \range{i}{j}. Each iterator in the range \range{i}{j} is dereferenced exactly once. \pnum @@ -1389,7 +1445,10 @@ from \tcode{*ranges::begin(rg)}. For \tcode{vector}, if \tcode{R} models -neither \tcode{ranges::\libconcept{sized_range}} nor \tcode{ranges::\libconcept{forward_range}}, +\tcode{ranges::\libconcept{approximately_sized_range}} +but not \tcode{ranges::\libconcept{sized_range}} or models +\tcode{ranges::\libconcept{input_range}} +but not \tcode{ranges::\libconcept{forward_range}}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. \pnum @@ -1397,6 +1456,12 @@ Constructs a sequence container equal to the range \tcode{rg}. Each iterator in the range \tcode{rg} is dereferenced exactly once. +\pnum +\recommended +If \tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}} and +\tcode{ranges::distance(\linebreak{}rg) <= ranges::reserve_hint(rg)} is \tcode{true}, +an implementation should not perform any reallocation. + \pnum \ensures \tcode{distance(begin(), end()) == ranges::distance(rg)} is \tcode{true}. @@ -1449,7 +1514,7 @@ \pnum \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X} and \oldconcept{MoveAssignable}. @@ -1464,8 +1529,7 @@ \pnum \returns -An iterator that points to -the new element constructed from \tcode{args} into \tcode{a}. +An iterator that points to the new element. \end{itemdescr} \indexcont{insert}% @@ -1481,7 +1545,7 @@ \pnum \expects \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is also \oldconcept{CopyAssignable}. \pnum @@ -1505,7 +1569,7 @@ \pnum \expects \tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is also \oldconcept{MoveAssignable}. \pnum @@ -1554,18 +1618,18 @@ \pnum \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}, and \tcode{T} meets the \oldconcept{MoveConstructible}, -\oldconcept{MoveAssignable}, and +\oldconcept{MoveAs\-signable}, and \oldconcept{Swappable}\iref{swappable.requirements} requirements. Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}. \pnum \effects -Inserts copies of elements in \tcode{[i, j)} before \tcode{p}. +Inserts copies of elements in \range{i}{j} before \tcode{p}. Each iterator in the range \range{i}{j} shall be dereferenced exactly once. \pnum @@ -1589,12 +1653,12 @@ \expects \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*ranges::begin(rg)}. -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}, and \tcode{T} meets the -\oldconcept{MoveConstructible}, -\oldconcept{Move\-Assignable}, and +\oldconcept{Move\-Constructible}, +\oldconcept{MoveAssignable}, and \oldconcept{Swappable}\iref{swappable.requirements} requirements. \tcode{rg} and \tcode{a} do not overlap. @@ -1632,7 +1696,7 @@ \pnum \expects -For \tcode{vector} and \tcode{deque}, +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, \tcode{T} is \oldconcept{MoveAssignable}. \pnum @@ -1657,11 +1721,12 @@ \pnum \expects -For \tcode{vector} and \tcode{deque}, \tcode{T} is \oldconcept{MoveAssignable}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is \oldconcept{MoveAssignable}. \pnum \effects -Erases the elements in the range \tcode{[q1, q2)}. +Erases the elements in the range \range{q1}{q2}. \pnum \returns @@ -1718,7 +1783,7 @@ \pnum \effects -Replaces elements in \tcode{a} with a copy of \tcode{[i, j)}. +Replaces elements in \tcode{a} with a copy of \range{i}{j}. Invalidates all references, pointers and iterators referring to the elements of \tcode{a}. For \tcode{vector} and \tcode{deque}, @@ -1747,7 +1812,10 @@ from \tcode{*ranges::begin(rg)}. For \tcode{vector}, if \tcode{R} models -neither \tcode{ranges::\libconcept{sized_range}} nor \tcode{ranges::\libconcept{forward_range}}, +\tcode{ranges::\libconcept{approximately_sized_range}} +but not \tcode{ranges::\libconcept{sized_range}} or models +\tcode{ranges::\libconcept{input_range}} +but not \tcode{ranges::\libconcept{forward_range}}, \tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. \tcode{rg} and \tcode{a} do not overlap. @@ -1759,6 +1827,12 @@ For \tcode{vector} and \tcode{deque}, also invalidates the past-the-end iterator. Each iterator in the range \tcode{rg} is dereferenced exactly once. + +\pnum +\recommended +If \tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}} and +\tcode{ranges::distance(\linebreak{}rg) <= ranges::reserve_hint(rg)} is \tcode{true}, +an implementation should not perform any reallocation. \end{itemdescr} \begin{itemdecl} @@ -1847,6 +1921,10 @@ \result \tcode{reference; const_reference} for constant \tcode{a}. +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + \pnum \returns \tcode{*a.begin()} @@ -1858,6 +1936,7 @@ \tcode{array}, \tcode{deque}, \tcode{forward_list}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -1871,6 +1950,10 @@ \result \tcode{reference; const_reference} for constant \tcode{a}. +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + \pnum \effects Equivalent to: @@ -1886,6 +1969,7 @@ \tcode{basic_string}, \tcode{array}, \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -1948,6 +2032,7 @@ \remarks Required for \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -2060,6 +2145,7 @@ Required for \tcode{basic_string}, \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -2086,6 +2172,7 @@ Required for \tcode{basic_string}, \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -2116,6 +2203,7 @@ \remarks Required for \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -2130,7 +2218,7 @@ \keyword{void} \pnum -\expects +\hardexpects \tcode{a.empty()} is \tcode{false}. \pnum @@ -2155,7 +2243,7 @@ \keyword{void} \pnum -\expects +\hardexpects \tcode{a.empty()} is \tcode{false}. \pnum @@ -2167,6 +2255,7 @@ Required for \tcode{basic_string}, \tcode{deque}, +\tcode{inplace_vector}, \tcode{list}, and \tcode{vector}. \end{itemdescr} @@ -2178,7 +2267,11 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a} +\tcode{reference; const_reference} for constant \tcode{a}. + +\pnum +\hardexpects +\tcode{n < a.size()} is \tcode{true}. \pnum \effects @@ -2189,7 +2282,8 @@ Required for \tcode{basic_string}, \tcode{array}, -\tcode{deque}, and +\tcode{deque}, +\tcode{inplace_vector}, and \tcode{vector}. \end{itemdescr} @@ -2200,7 +2294,7 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a} +\tcode{reference; const_reference} for constant \tcode{a}. \pnum \returns @@ -2215,7 +2309,8 @@ Required for \tcode{basic_string}, \tcode{array}, -\tcode{deque}, and +\tcode{deque}, +\tcode{inplace_vector}, and \tcode{vector}. \end{itemdescr} @@ -2288,27 +2383,27 @@ public: // \ref{container.node.cons}, constructors, copy, and assignment constexpr @\placeholdernc{node-handle}@() noexcept : ptr_(), alloc_() {} - @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&&) noexcept; - @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&&); + constexpr @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&&) noexcept; + constexpr @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&&); // \ref{container.node.dtor}, destructor - ~@\placeholdernc{node-handle}@(); + constexpr ~@\placeholdernc{node-handle}@(); // \ref{container.node.observers}, observers - value_type& value() const; // not present for map containers - key_type& key() const; // not present for set containers - mapped_type& mapped() const; // not present for set containers + constexpr value_type& value() const; // not present for map containers + key_type& key() const; // not present for set containers + constexpr mapped_type& mapped() const; // not present for set containers - allocator_type get_allocator() const; - explicit operator bool() const noexcept; - [[nodiscard]] bool empty() const noexcept; + constexpr allocator_type get_allocator() const; + constexpr explicit operator bool() const noexcept; + constexpr bool empty() const noexcept; // \ref{container.node.modifiers}, modifiers - void swap(@\placeholdernc{node-handle}@&) + constexpr void swap(@\placeholdernc{node-handle}@&) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); - friend void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { + constexpr friend void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } }; @@ -2317,7 +2412,7 @@ \rSec3[container.node.cons]{Constructors, copy, and assignment} \begin{itemdecl} -@\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&& nh) noexcept; +constexpr @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&& nh) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2330,7 +2425,7 @@ \end{itemdescr} \begin{itemdecl} -@\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&& nh); +constexpr @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&& nh); \end{itemdecl} \begin{itemdescr} @@ -2372,7 +2467,7 @@ \rSec3[container.node.dtor]{Destructor} \begin{itemdecl} -~@\placeholdernc{node-handle}@(); +constexpr ~@\placeholdernc{node-handle}@(); \end{itemdecl} \begin{itemdescr} @@ -2387,7 +2482,7 @@ \rSec3[container.node.observers]{Observers} \begin{itemdecl} -value_type& value() const; +constexpr value_type& value() const; \end{itemdecl} \begin{itemdescr} @@ -2430,7 +2525,7 @@ \end{itemdescr} \begin{itemdecl} -mapped_type& mapped() const; +constexpr mapped_type& mapped() const; \end{itemdecl} \begin{itemdescr} @@ -2449,9 +2544,8 @@ Nothing. \end{itemdescr} - \begin{itemdecl} -allocator_type get_allocator() const; +constexpr allocator_type get_allocator() const; \end{itemdecl} \begin{itemdescr} @@ -2469,7 +2563,7 @@ \end{itemdescr} \begin{itemdecl} -explicit operator bool() const noexcept; +constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -2479,7 +2573,7 @@ \end{itemdescr} \begin{itemdecl} -[[nodiscard]] bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -2491,7 +2585,7 @@ \rSec3[container.node.modifiers]{Modifiers} \begin{itemdecl} -void swap(@\placeholdernc{node-handle}@& nh) +constexpr void swap(@\placeholdernc{node-handle}@& nh) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); \end{itemdecl} @@ -2636,7 +2730,7 @@ \tcode{a2} denotes a value of a type with nodes compatible with type \tcode{X} (\tref{container.node.compat}), \item -\tcode{b} denotes a value or type \tcode{X} or \tcode{const X}, +\tcode{b} denotes a value of type \tcode{X} or \tcode{const X}, \item \tcode{u} denotes the name of a variable being declared, \item @@ -2667,7 +2761,7 @@ \item \tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, \item -\tcode{[q1, q2)} denotes a valid range of constant iterators in \tcode{a}, +\range{q1}{q2} denotes a valid range of constant iterators in \tcode{a}, \item \tcode{il} designates an object of type \tcode{initializer_list}, \item @@ -2710,12 +2804,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} @@ -2731,6 +2825,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}% @@ -3508,7 +3606,7 @@ \pnum \expects -\tcode{a.get_allocator() == a2.get_allocator()}. +\tcode{a.get_allocator() == a2.get_allocator()} is \tcode{true}. \pnum \effects @@ -3523,7 +3621,8 @@ \ensures Pointers and references to the transferred elements of \tcode{a2} refer to those same elements but as members of \tcode{a}. -Iterators referring to the transferred elements +If \tcode{a.begin()} and \tcode{a2.begin()} have the same type, +iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators into \tcode{a}, not into \tcode{a2}. @@ -3845,7 +3944,7 @@ \pnum \complexity -Logarithmic, +Logarithmic. \end{itemdescr} \indexordmem{upper_bound}% @@ -4152,7 +4251,7 @@ \tcode{i} and \tcode{j} denote input iterators that refer to \tcode{value_type}, \item -\tcode{[i, j)} denotes a valid range, +\range{i}{j} denotes a valid range, \item \tcode{rg} denotes a value of a type \tcode{R} that models \tcode{\exposconcept{container-compatible-range}}, @@ -4164,7 +4263,7 @@ \item \tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, \item -\tcode{[q1, q2)} denotes a valid range in \tcode{a}, +\range{q1}{q2} denotes a valid range in \tcode{a}, \item \tcode{il} denotes a value of type \tcode{initializer_list}, \item @@ -4209,11 +4308,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} @@ -4976,7 +5075,7 @@ \pnum \effects -Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}. +Equivalent to \tcode{a.insert(t)} for each element in \range{i}{j}. \pnum \complexity @@ -5339,7 +5438,7 @@ \pnum \effects -Erases all elements in the range \tcode{[q1, q2)}. +Erases all elements in the range \range{q1}{q2}. \pnum \returns @@ -5575,7 +5674,7 @@ The index of the bucket in which elements with keys equivalent to \tcode{k} would be found, if any such element existed. -The return value is in the range \tcode{[0, b.bucket_count())}. +The return value is in the range \range{0}{b.bucket_count()}. \pnum \complexity @@ -5598,7 +5697,7 @@ \pnum \ensures -The return value is in the range \tcode{[0, a_tran.bucket_count())}. +The return value is in the range \range{0}{a_tran.bucket_count()}. \pnum \returns @@ -5623,7 +5722,7 @@ \pnum \expects -\tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. +\tcode{n} shall be in the range \range{0}{b.bucket_count()}. \pnum \returns @@ -5646,7 +5745,7 @@ \pnum \expects -\tcode{n} is in the range \tcode{[0, b.bucket_count())}. +\tcode{n} is in the range \range{0}{b.bucket_count()}. \pnum \returns @@ -5670,7 +5769,7 @@ \pnum \expects -\tcode{n} is in the range \tcode{[0, b.bucket_count())}. +\tcode{n} is in the range \range{0}{b.bucket_count()}. \pnum \returns @@ -5693,7 +5792,7 @@ \pnum \expects -\tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. +\tcode{n} shall be in the range \range{0}{b.bucket_count()}. \pnum \returns @@ -5717,7 +5816,7 @@ \pnum \expects -\tcode{n} is in the range \tcode{[0, b.bucket_count())}. +\tcode{n} is in the range \range{0}{b.bucket_count()}. \pnum \returns @@ -5876,7 +5975,7 @@ \indextext{unordered associative containers!requirements}% The \tcode{insert}, \tcode{insert_range}, and \tcode{emplace} members shall not affect the validity of iterators if -\tcode{(N+n) <= z * B}, where \tcode{N} is the number of elements in +\tcode{(N + n) <= z * B}, where \tcode{N} is the number of elements in the container prior to the insert operation, \tcode{n} is the number of elements inserted, \tcode{B} is the container's bucket count, and \tcode{z} is the container's maximum load factor. @@ -5952,13 +6051,15 @@ \rSec1[sequences]{Sequence containers} -\rSec2[sequences.general]{In general} +\rSec2[sequences.general]{General} \pnum The headers \libheaderref{array}, \libheaderref{deque}, \libheaderrefx{forward_list}{forward.list.syn}, +\libheaderref{hive}, +\libheaderrefx{inplace_vector}{inplace.vector.syn}, \libheaderref{list}, and \libheaderref{vector} define class templates that meet the requirements for sequence containers. @@ -6017,166 +6118,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[array]{Class template \tcode{array}} \indexlibraryglobal{array}% @@ -6267,7 +6208,7 @@ constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] constexpr bool empty() const noexcept; + constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; @@ -6281,8 +6222,8 @@ constexpr reference back(); constexpr const_reference back() const; - constexpr T * data() noexcept; - constexpr const T * data() const noexcept; + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; }; template @@ -6295,12 +6236,11 @@ \pnum \indextext{\idxcode{array}!initialization}% \indextext{requirements!container}% -The conditions for an aggregate\iref{dcl.init.aggr} shall be -met. Class \tcode{array} relies on the implicitly-declared special +An \tcode{array} relies on the implicitly-declared special member functions\iref{class.default.ctor,class.dtor,class.copy.ctor} to conform to the container requirements table in~\ref{container.requirements}. In addition to the requirements specified in the container requirements table, -the implicit move constructor and move assignment operator for \tcode{array} +the implicitly-declared move constructor and move assignment operator for \tcode{array} require that \tcode{T} be \oldconcept{MoveConstructible} or \oldconcept{MoveAssignable}, respectively. @@ -6422,7 +6362,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 @@ -6443,7 +6383,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 @@ -6501,6 +6441,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 + constexpr bool operator==(const deque& x, const deque& y); + template + constexpr @\placeholder{synth-three-way-result}@ operator<=>(const deque& x, + @\itcorr@ const deque& y); + + template + constexpr void swap(deque& x, deque& y) + noexcept(noexcept(x.swap(y))); + + // \ref{deque.erasure}, erasure + template + constexpr typename deque::size_type + erase(deque& c, const U& value); + template + constexpr 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} @@ -6527,6 +6503,10 @@ that are not described in one of these tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template> @@ -6547,97 +6527,98 @@ using const_reverse_iterator = std::reverse_iterator; // \ref{deque.cons}, construct/copy/destroy - deque() : deque(Allocator()) { } - explicit deque(const Allocator&); - explicit deque(size_type n, const Allocator& = Allocator()); - deque(size_type n, const T& value, const Allocator& = Allocator()); + constexpr deque() : deque(Allocator()) { } + constexpr explicit deque(const Allocator&); + constexpr explicit deque(size_type n, const Allocator& = Allocator()); + constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); template - deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - deque(from_range_t, R&& rg, const Allocator& = Allocator()); - deque(const deque& x); - deque(deque&&); - deque(const deque&, const type_identity_t&); - deque(deque&&, const type_identity_t&); - deque(initializer_list, const Allocator& = Allocator()); - - ~deque(); - deque& operator=(const deque& x); - deque& operator=(deque&& x) + constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr deque(const deque& x); + constexpr deque(deque&&); + constexpr deque(const deque&, const type_identity_t&); + constexpr deque(deque&&, const type_identity_t&); + constexpr deque(initializer_list, const Allocator& = Allocator()); + + constexpr ~deque(); + constexpr deque& operator=(const deque& x); + constexpr deque& operator=(deque&& x) noexcept(allocator_traits::is_always_equal::value); - deque& operator=(initializer_list); + constexpr deque& operator=(initializer_list); template - void assign(InputIterator first, InputIterator last); + constexpr void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void assign_range(R&& rg); - void assign(size_type n, const T& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // \ref{deque.capacity}, capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - void resize(size_type sz); - void resize(size_type sz, const T& c); - void shrink_to_fit(); + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + constexpr void shrink_to_fit(); // element access - reference operator[](size_type n); - const_reference operator[](size_type n) const; - reference at(size_type n); - const_reference at(size_type n) const; - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + // \ref{deque.modifiers}, modifiers - template reference emplace_front(Args&&... args); - template reference emplace_back(Args&&... args); - template iterator emplace(const_iterator position, Args&&... args); + template constexpr reference emplace_front(Args&&... args); + template constexpr reference emplace_back(Args&&... args); + template constexpr iterator emplace(const_iterator position, Args&&... args); - void push_front(const T& x); - void push_front(T&& x); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); - void push_back(const T& x); - void push_back(T&& x); + constexpr void prepend_range(R&& rg); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@ R> - void append_range(R&& rg); + constexpr void append_range(R&& rg); - iterator insert(const_iterator position, const T& x); - iterator insert(const_iterator position, T&& x); - iterator insert(const_iterator position, size_type n, const T& x); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); template - iterator insert(const_iterator position, InputIterator first, InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range(const_iterator position, R&& rg); - iterator insert(const_iterator position, initializer_list); + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list); - void pop_front(); - void pop_back(); + constexpr void pop_front(); + constexpr void pop_back(); - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - void swap(deque&) + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(deque&) noexcept(allocator_traits::is_always_equal::value); - void clear() noexcept; + constexpr void clear() noexcept; }; template>> @@ -6654,7 +6635,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} -explicit deque(const Allocator&); +constexpr explicit deque(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -6671,13 +6652,13 @@ \indexlibraryctor{deque}% \begin{itemdecl} -explicit deque(size_type n, const Allocator& = Allocator()); +constexpr explicit deque(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{deque}. \pnum \effects @@ -6691,13 +6672,13 @@ \indexlibraryctor{deque}% \begin{itemdecl} -deque(size_type n, const T& value, const Allocator& = Allocator()); +constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{deque}. \pnum \effects @@ -6714,7 +6695,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} template - deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6734,7 +6715,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - deque(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6752,13 +6733,13 @@ \indexlibrarymember{resize}{deque}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{deque}. \pnum \effects @@ -6769,13 +6750,13 @@ \indexlibrarymember{resize}{deque}% \begin{itemdecl} -void resize(size_type sz, const T& c); +constexpr void resize(size_type sz, const T& c); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{deque}. \pnum \effects @@ -6786,13 +6767,13 @@ \indexlibrarymember{shrink_to_fit}{deque}% \begin{itemdecl} -void shrink_to_fit(); +constexpr void shrink_to_fit(); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{deque}. \pnum \effects @@ -6828,27 +6809,27 @@ \indexlibrarymember{push_back}{deque}% \indexlibrarymember{emplace}{deque}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); template - iterator insert(const_iterator position, - InputIterator first, InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range(const_iterator position, R&& rg); -iterator insert(const_iterator position, initializer_list); - -template reference emplace_front(Args&&... args); -template reference emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_front(Args&&... args); +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); -void push_back(const T& x); -void push_back(T&& x); + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@ R> - void append_range(R&& rg); + constexpr void append_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -6873,7 +6854,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. @@ -6884,10 +6865,10 @@ \indexlibrarymember{erase}{deque}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); -void pop_front(); -void pop_back(); +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); \end{itemdecl} \begin{itemdescr} @@ -6920,7 +6901,7 @@ \indexlibrarymember{erase}{deque}% \begin{itemdecl} template - typename deque::size_type + constexpr typename deque::size_type erase(deque& c, const U& value); \end{itemdecl} @@ -6939,7 +6920,7 @@ \indexlibrarymember{erase_if}{deque}% \begin{itemdecl} template - typename deque::size_type + constexpr typename deque::size_type erase_if(deque& c, Predicate pred); \end{itemdecl} @@ -6955,6 +6936,43 @@ \end{codeblock} \end{itemdescr} +\rSec2[forward.list.syn]{Header \tcode{} synopsis} + +\indexheader{forward_list}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{forward.list}, class template \tcode{forward_list} + template> class forward_list; + + template + constexpr bool operator==(const forward_list& x, + const forward_list& y); + template + constexpr @\placeholder{synth-three-way-result}@ operator<=>(const forward_list& x, + @\itcorr@ const forward_list& y); + + template + constexpr void swap(forward_list& x, forward_list& y) + noexcept(noexcept(x.swap(y))); + + // \ref{forward.list.erasure}, erasure + template + constexpr typename forward_list::size_type + erase(forward_list& c, const U& value); + template + constexpr 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} @@ -6973,7 +6991,7 @@ A \tcode{forward_list} meets all of the requirements of a container\iref{container.reqmts}, except that the \tcode{size()} member function is not provided and -\tcode{operator==} has linear complexity, +\tcode{operator==} has linear complexity. A \tcode{forward_list} also meets all of the requirements for an allocator-aware container\iref{container.alloc.reqmts}. In addition, a \tcode{forward_list} @@ -6992,6 +7010,10 @@ take fully-open ranges, not semi-open ranges. \end{note} +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template> @@ -7010,105 +7032,108 @@ using const_iterator = @\impdefx{type of \tcode{forward_list::const_iterator}}@; // see \ref{container.requirements} // \ref{forward.list.cons}, construct/copy/destroy - forward_list() : forward_list(Allocator()) { } - explicit forward_list(const Allocator&); - explicit forward_list(size_type n, const Allocator& = Allocator()); - forward_list(size_type n, const T& value, const Allocator& = Allocator()); + constexpr forward_list() : forward_list(Allocator()) { } + constexpr explicit forward_list(const Allocator&); + constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); + constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); template - forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr forward_list(InputIterator first, InputIterator last, + const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); - forward_list(const forward_list& x); - forward_list(forward_list&& x); - forward_list(const forward_list& x, const type_identity_t&); - forward_list(forward_list&& x, const type_identity_t&); - forward_list(initializer_list, const Allocator& = Allocator()); - ~forward_list(); - forward_list& operator=(const forward_list& x); - forward_list& operator=(forward_list&& x) + constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr forward_list(const forward_list& x); + constexpr forward_list(forward_list&& x); + constexpr forward_list(const forward_list& x, const type_identity_t&); + constexpr forward_list(forward_list&& x, const type_identity_t&); + constexpr forward_list(initializer_list, const Allocator& = Allocator()); + constexpr ~forward_list(); + constexpr forward_list& operator=(const forward_list& x); + constexpr forward_list& operator=(forward_list&& x) noexcept(allocator_traits::is_always_equal::value); - forward_list& operator=(initializer_list); + constexpr forward_list& operator=(initializer_list); template - void assign(InputIterator first, InputIterator last); + constexpr void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void assign_range(R&& rg); - void assign(size_type n, const T& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // \ref{forward.list.iter}, iterators - iterator before_begin() noexcept; - const_iterator before_begin() const noexcept; - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator before_begin() noexcept; + constexpr const_iterator before_begin() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cbefore_begin() const noexcept; - const_iterator cend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cbefore_begin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{forward.list.access}, element access - reference front(); - const_reference front() const; + constexpr reference front(); + constexpr const_reference front() const; // \ref{forward.list.modifiers}, modifiers - template reference emplace_front(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); + template constexpr reference emplace_front(Args&&... args); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); - void pop_front(); + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); - template iterator emplace_after(const_iterator position, Args&&... args); - iterator insert_after(const_iterator position, const T& x); - iterator insert_after(const_iterator position, T&& x); + template + constexpr iterator emplace_after(const_iterator position, Args&&... args); + constexpr iterator insert_after(const_iterator position, const T& x); + constexpr iterator insert_after(const_iterator position, T&& x); - iterator insert_after(const_iterator position, size_type n, const T& x); + constexpr iterator insert_after(const_iterator position, size_type n, const T& x); template - iterator insert_after(const_iterator position, InputIterator first, InputIterator last); - iterator insert_after(const_iterator position, initializer_list il); + constexpr iterator insert_after(const_iterator position, + InputIterator first, InputIterator last); + constexpr iterator insert_after(const_iterator position, initializer_list il); template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range_after(const_iterator position, R&& rg); + constexpr iterator insert_range_after(const_iterator position, R&& rg); - iterator erase_after(const_iterator position); - iterator erase_after(const_iterator position, const_iterator last); - void swap(forward_list&) + constexpr iterator erase_after(const_iterator position); + constexpr iterator erase_after(const_iterator position, const_iterator last); + constexpr void swap(forward_list&) noexcept(allocator_traits::is_always_equal::value); - void resize(size_type sz); - void resize(size_type sz, const value_type& c); - void clear() noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const value_type& c); + constexpr void clear() noexcept; // \ref{forward.list.ops}, \tcode{forward_list} operations - void splice_after(const_iterator position, forward_list& x); - void splice_after(const_iterator position, forward_list&& x); - void splice_after(const_iterator position, forward_list& x, const_iterator i); - void splice_after(const_iterator position, forward_list&& x, const_iterator i); - void splice_after(const_iterator position, forward_list& x, + constexpr void splice_after(const_iterator position, forward_list& x); + constexpr void splice_after(const_iterator position, forward_list&& x); + constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); + constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i); + constexpr void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); - void splice_after(const_iterator position, forward_list&& x, + constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last); - size_type remove(const T& value); - template size_type remove_if(Predicate pred); + constexpr size_type remove(const T& value); + template constexpr size_type remove_if(Predicate pred); size_type unique(); - template size_type unique(BinaryPredicate binary_pred); + template constexpr size_type unique(BinaryPredicate binary_pred); - void merge(forward_list& x); - void merge(forward_list&& x); - template void merge(forward_list& x, Compare comp); - template void merge(forward_list&& x, Compare comp); + constexpr void merge(forward_list& x); + constexpr void merge(forward_list&& x); + template constexpr void merge(forward_list& x, Compare comp); + template constexpr void merge(forward_list&& x, Compare comp); - void sort(); - template void sort(Compare comp); + constexpr void sort(); + template constexpr void sort(Compare comp); - void reverse() noexcept; + constexpr void reverse() noexcept; }; template>> @@ -7132,7 +7157,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -explicit forward_list(const Allocator&); +constexpr explicit forward_list(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -7147,13 +7172,13 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -explicit forward_list(size_type n, const Allocator& = Allocator()); +constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{forward_list}. \pnum \effects @@ -7167,13 +7192,13 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -forward_list(size_type n, const T& value, const Allocator& = Allocator()); +constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. \pnum \effects @@ -7187,7 +7212,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} template - forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7203,7 +7228,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7222,9 +7247,9 @@ \indexlibrarymember{before_begin}{forward_list}% \indexlibrarymember{cbefore_begin}{forward_list}% \begin{itemdecl} -iterator before_begin() noexcept; -const_iterator before_begin() const noexcept; -const_iterator cbefore_begin() const noexcept; +constexpr iterator before_begin() noexcept; +constexpr const_iterator before_begin() const noexcept; +constexpr const_iterator cbefore_begin() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -7247,8 +7272,8 @@ \indexlibrarymember{front}{forward_list}% \begin{itemdecl} -reference front(); -const_reference front() const; +constexpr reference front(); +constexpr const_reference front() const; \end{itemdecl} \begin{itemdescr} @@ -7260,10 +7285,13 @@ \rSec3[forward.list.modifiers]{Modifiers} \pnum -None of the overloads of \tcode{insert_after} shall affect the validity of iterators and -references, and \tcode{erase_after} shall invalidate only iterators and references to -the erased elements. If an exception is thrown during \tcode{insert_after} there shall -be no effect. Inserting \tcode{n} elements into a \tcode{forward_list} is linear in +The member functions in this subclause +do not affect the validity of iterators and references +when inserting elements, and when erasing elements +invalidate iterators and references to the erased elements only. +If an exception is thrown by any of these member functions +there is no effect on the container. +Inserting \tcode{n} elements into a \tcode{forward_list} is linear in \tcode{n}, and the number of calls to the copy or move constructor of \tcode{T} is exactly equal to \tcode{n}. Erasing \tcode{n} elements from a \tcode{forward_list} is linear in \tcode{n} and the number of calls to the destructor of type \tcode{T} is @@ -7271,7 +7299,7 @@ \indexlibrarymember{emplace_front}{forward_list}% \begin{itemdecl} -template reference emplace_front(Args&&... args); +template constexpr reference emplace_front(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7283,8 +7311,8 @@ \indexlibrarymember{push_front}{forward_list}% \begin{itemdecl} -void push_front(const T& x); -void push_front(T&& x); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); \end{itemdecl} \begin{itemdescr} @@ -7296,7 +7324,7 @@ \indexlibrarymember{prepend_range}{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); + constexpr void prepend_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -7310,7 +7338,7 @@ \indexlibrarymember{pop}{forward_list}% \begin{itemdecl} -void pop_front(); +constexpr void pop_front(); \end{itemdecl} \begin{itemdescr} @@ -7321,7 +7349,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, const T& x); +constexpr iterator insert_after(const_iterator position, const T& x); \end{itemdecl} \begin{itemdescr} @@ -7342,7 +7370,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, T&& x); +constexpr iterator insert_after(const_iterator position, T&& x); \end{itemdecl} \begin{itemdescr} @@ -7363,7 +7391,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, size_type n, const T& x); +constexpr iterator insert_after(const_iterator position, size_type n, const T& x); \end{itemdecl} \begin{itemdescr} @@ -7386,7 +7414,8 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} template - iterator insert_after(const_iterator position, InputIterator first, InputIterator last); + constexpr iterator insert_after(const_iterator position, + InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -7411,7 +7440,7 @@ \indexlibrarymember{insert_range_after}{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range_after(const_iterator position, R&& rg); + constexpr iterator insert_range_after(const_iterator position, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -7435,7 +7464,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, initializer_list il); +constexpr iterator insert_after(const_iterator position, initializer_list il); \end{itemdecl} \begin{itemdescr} @@ -7448,7 +7477,7 @@ \indexlibrarymember{emplace_after}{forward_list}% \begin{itemdecl} template - iterator emplace_after(const_iterator position, Args&&... args); + constexpr iterator emplace_after(const_iterator position, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7471,7 +7500,7 @@ \indexlibrarymember{erase_after}{forward_list}% \begin{itemdecl} -iterator erase_after(const_iterator position); +constexpr iterator erase_after(const_iterator position); \end{itemdecl} \begin{itemdescr} @@ -7494,7 +7523,7 @@ \end{itemdescr} \begin{itemdecl} -iterator erase_after(const_iterator position, const_iterator last); +constexpr iterator erase_after(const_iterator position, const_iterator last); \end{itemdecl} \begin{itemdescr} @@ -7517,13 +7546,13 @@ \indexlibrarymember{resize}{forward_list}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{forward_list}. \pnum \effects @@ -7533,13 +7562,13 @@ \end{itemdescr} \begin{itemdecl} -void resize(size_type sz, const value_type& c); +constexpr void resize(size_type sz, const value_type& c); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. \pnum \effects @@ -7551,7 +7580,7 @@ \indexlibrarymember{clear}{forward_list}% \begin{itemdecl} -void clear() noexcept; +constexpr void clear() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7582,8 +7611,8 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x); -void splice_after(const_iterator position, forward_list&& x); +constexpr void splice_after(const_iterator position, forward_list& x); +constexpr void splice_after(const_iterator position, forward_list&& x); \end{itemdecl} \begin{itemdescr} @@ -7613,8 +7642,8 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x, const_iterator i); -void splice_after(const_iterator position, forward_list&& x, const_iterator i); +constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); +constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i); \end{itemdecl} \begin{itemdescr} @@ -7645,10 +7674,10 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x, - const_iterator first, const_iterator last); -void splice_after(const_iterator position, forward_list&& x, - const_iterator first, const_iterator last); +constexpr void splice_after(const_iterator position, forward_list& x, + const_iterator first, const_iterator last); +constexpr void splice_after(const_iterator position, forward_list&& x, + const_iterator first, const_iterator last); \end{itemdecl} \begin{itemdescr} @@ -7676,8 +7705,8 @@ \indexlibrarymember{remove}{forward_list}% \indexlibrarymember{remove_if}{forward_list}% \begin{itemdecl} -size_type remove(const T& value); -template size_type remove_if(Predicate pred); +constexpr size_type remove(const T& value); +template constexpr size_type remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -7709,8 +7738,8 @@ \indexlibrarymember{unique}{forward_list}% \begin{itemdecl} -size_type unique(); -template size_type unique(BinaryPredicate binary_pred); +constexpr size_type unique(); +template constexpr size_type unique(BinaryPredicate binary_pred); \end{itemdecl} \begin{itemdescr} @@ -7748,10 +7777,10 @@ \indexlibrarymember{merge}{forward_list}% \begin{itemdecl} -void merge(forward_list& x); -void merge(forward_list&& x); -template void merge(forward_list& x, Compare comp); -template void merge(forward_list&& x, Compare comp); +constexpr void merge(forward_list& x); +constexpr void merge(forward_list&& x); +template constexpr void merge(forward_list& x, Compare comp); +template constexpr void merge(forward_list&& x, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -7792,8 +7821,8 @@ \indexlibrarymember{sort}{forward_list}% \begin{itemdecl} -void sort(); -template void sort(Compare comp); +constexpr void sort(); +template constexpr void sort(Compare comp); \end{itemdecl} \begin{itemdescr} @@ -7814,7 +7843,7 @@ \indexlibrarymember{reverse}{forward_list}% \begin{itemdecl} -void reverse() noexcept; +constexpr void reverse() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7833,20 +7862,23 @@ \indexlibrarymember{erase}{forward_list}% \begin{itemdecl} template - typename forward_list::size_type + constexpr typename forward_list::size_type erase(forward_list& c, const U& value); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return erase_if(c, [\&](auto\& elem) \{ return elem == value; \});} +Equivalent to: +\begin{codeblock} +return erase_if(c, [&](const auto& elem) -> bool { return elem == value; }); +\end{codeblock} \end{itemdescr} \indexlibrarymember{erase_if}{forward_list}% \begin{itemdecl} template - typename forward_list::size_type + constexpr typename forward_list::size_type erase_if(forward_list& c, Predicate pred); \end{itemdecl} @@ -7856,82 +7888,175 @@ Equivalent to: \tcode{return c.remove_if(pred);} \end{itemdescr} -\rSec2[list]{Class template \tcode{list}} +\rSec2[hive.syn]{Header \tcode{} synopsis} -\rSec3[list.overview]{Overview} +\indexheader{hive}% +\begin{codeblock} + +#include // see \ref{initializer.list.syn} +#include // see \ref{compare.syn} + +namespace std { + struct @\libglobal{hive_limits}@ { + size_t @\libmember{min}{hive_limits}@; + size_t @\libmember{max}{hive_limits}@; + constexpr hive_limits(size_t minimum, size_t maximum) noexcept + : min(minimum), max(maximum) {} + }; + + // \ref {hive}, class template \tcode{hive} + template> class hive; + + template + void swap(hive& x, hive& y) + noexcept(noexcept(x.swap(y))); + + template + typename hive::size_type + erase(hive& c, const U& value); + + template + typename hive::size_type + erase_if(hive& c, Predicate pred); + + namespace pmr { + template + using hive = std::hive>; + } +} +\end{codeblock} + +\rSec2[hive]{Class template \tcode{hive}} + +\rSec3[hive.overview]{Overview} \pnum -\indexlibraryglobal{list}% -A -\tcode{list} -is a sequence container that supports -bidirectional iterators and allows constant time insert and erase -operations anywhere within the sequence, with storage management handled -automatically. Unlike vectors\iref{vector} and deques\iref{deque}, -fast random access to list elements is not supported, but many -algorithms only need sequential access anyway. +A \tcode{hive} is a type of sequence container +that provides constant-time insertion and erasure operations. +Storage is automatically managed in multiple memory blocks, +referred to as \defnx{element blocks}{element block}. +Insertion position is determined by the container, and insertion +may re-use the memory locations of erased elements. \pnum -A \tcode{list} meets all of the requirements -of a container\iref{container.reqmts}, +Element blocks which contain elements are referred to +as \defnadjx{active}{blocks}{block}, +those which do not are referred to as \defnadjx{reserved}{blocks}{block}. +Active blocks which become empty of elements are +either deallocated or become reserved blocks. +Reserved blocks become active blocks when they are used to store elements. +A user can create additional reserved blocks by calling \tcode{reserve}. + +\pnum +Erasures use unspecified techniques of constant time complexity +to identify the memory locations of erased elements, +which are subsequently skipped during iteration, +as opposed to relocating subsequent elements during erasure. + +\pnum +Active block capacities have +an \impldef{growth factor of \tcode{hive} active block capacities} growth factor +(which need not be integral), +for example a new active block's capacity could be equal to +the summed capacities of the pre-existing active blocks. + +\pnum +Limits can be placed on +both the minimum and maximum element capacities of element blocks, +both by users and implementations. +\begin{itemize} +\item +The minimum limit shall be no larger than the maximum limit. +\item +When limits are not specified by a user during construction, +the implementation's default limits are used. +\item +The default limits of an implementation are not guaranteed to be the same as +the minimum and maximum possible capacities +for an implementation's element blocks. +\begin{note} +To allow latitude for +both implementation-specific and user-directed optimization. +\end{note} +The latter are defined as hard limits. +The maximum hard limit shall be no larger than +\tcode{std::allocator_traits::max_size()}. +\item +If user-specified limits are not within hard limits, or +if the specified minimum limit is greater than the specified maximum limit, +the behavior is undefined. +\item +An element block is said to be \defnx{within the bounds}{element block!bounds} +of a pair of minimum/maximum limits +when its capacity is greater-or-equal-to the minimum limit and +less-than-or-equal-to the maximum limit. +\end{itemize} + +\pnum +A \tcode{hive} conforms to +the requirements for containers\iref{container.reqmts}, +with the exception of operators \tcode{==} and \tcode{!=}. +A \tcode{hive} also meets the requirements of a reversible container\iref{container.rev.reqmts}, of an allocator-aware container\iref{container.alloc.reqmts}, and -of a sequence container, -including most of the optional sequence container -requirements\iref{sequence.reqmts}. -The exceptions are the -\tcode{operator[]} -and -\tcode{at} -member functions, which are not provided. -\begin{footnote} -These member functions -are only provided by containers whose iterators -are random access iterators. -\end{footnote} -Descriptions are provided here only for operations on -\tcode{list} -that are not described in one of these tables -or for operations where there is additional semantic information. +some of the requirements of a sequence container\iref{sequence.reqmts}. +Descriptions are provided here only for operations on \tcode{hive} +that are not described in that table or for operations +where there is additional semantic information. + +\pnum +The iterators of \tcode{hive} meet +the \oldconcept{BidirectionalIterator} requirements +but also model \tcode{\libconcept{three_way_comparable}}. \begin{codeblock} namespace std { template> - class list { + class @\libglobal{hive}@ { public: // types - using value_type = T; - using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = @\impdefx{type of \tcode{list::size_type}}@; // see \ref{container.requirements} - using difference_type = @\impdefx{type of \tcode{list::difference_type}}@; // see \ref{container.requirements} - using iterator = @\impdefx{type of \tcode{list::iterator}}@; // see \ref{container.requirements} - using const_iterator = @\impdefx{type of \tcode{list::const_iterator}}@; // see \ref{container.requirements} - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - // \ref{list.cons}, construct/copy/destroy - list() : list(Allocator()) { } - explicit list(const Allocator&); - explicit list(size_type n, const Allocator& = Allocator()); - list(size_type n, const T& value, const Allocator& = Allocator()); + using value_type = T; + using allocator_type = Allocator; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = @\impdef@; // see \ref{container.requirements} + using difference_type = @\impdef@; // see \ref{container.requirements} + using iterator = @\impdef@; // see \ref{container.requirements} + using const_iterator = @\impdef@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; // see \ref{container.requirements} + using const_reverse_iterator = std::reverse_iterator; // see \ref{container.requirements} + + // \ref{hive.cons}, construct/copy/destroy + constexpr hive() noexcept(noexcept(Allocator())) : hive(Allocator()) {} + constexpr explicit hive(const Allocator&) noexcept; + constexpr explicit hive(hive_limits block_limits) : hive(block_limits, Allocator()) {} + constexpr hive(hive_limits block_limits, const Allocator&); + explicit hive(size_type n, const Allocator& = Allocator()); + hive(size_type n, hive_limits block_limits, const Allocator& = Allocator()); + hive(size_type n, const T& value, const Allocator& = Allocator()); + hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator()); + template + hive(InputIterator first, InputIterator last, const Allocator& = Allocator()); template - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + hive(InputIterator first, InputIterator last, hive_limits block_limits, + const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - list(from_range_t, R&& rg, const Allocator& = Allocator()); - list(const list& x); - list(list&& x); - list(const list&, const type_identity_t&); - list(list&&, const type_identity_t&); - list(initializer_list, const Allocator& = Allocator()); - ~list(); - list& operator=(const list& x); - list& operator=(list&& x) - noexcept(allocator_traits::is_always_equal::value); - list& operator=(initializer_list); + hive(from_range_t, R&& rg, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator()); + hive(const hive& x); + hive(hive&&) noexcept; + hive(const hive& x, const type_identity_t& alloc); + hive(hive&&, const type_identity_t& alloc); + hive(initializer_list il, const Allocator& = Allocator()); + hive(initializer_list il, hive_limits block_limits, const Allocator& = Allocator()); + ~hive(); + + hive& operator=(const hive& x); + hive& operator=(hive&& x) noexcept(@\seebelow@); + hive& operator=(initializer_list); template void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> @@ -7941,1083 +8066,2964 @@ allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - // \ref{list.capacity}, capacity - [[nodiscard]] bool empty() const noexcept; + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // \ref{hive.capacity}, capacity + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; - void resize(size_type sz); - void resize(size_type sz, const T& c); - - // element access - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - // \ref{list.modifiers}, modifiers - template reference emplace_front(Args&&... args); - template reference emplace_back(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); - template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); - void pop_front(); - void push_back(const T& x); - void push_back(T&& x); + size_type capacity() const noexcept; + void reserve(size_type n); + void shrink_to_fit(); + void trim_capacity() noexcept; + void trim_capacity(size_type n) noexcept; + constexpr hive_limits block_capacity_limits() const noexcept; + static constexpr hive_limits block_capacity_default_limits() noexcept; + static constexpr hive_limits block_capacity_hard_limits() noexcept; + void reshape(hive_limits block_limits); + + // \ref{hive.modifiers}, modifiers + template iterator emplace(Args&&... args); + template iterator emplace_hint(const_iterator hint, Args&&... args); + iterator insert(const T& x); + iterator insert(T&& x); + iterator insert(const_iterator hint, const T& x); + iterator insert(const_iterator hint, T&& x); + void insert(initializer_list il); template<@\exposconcept{container-compatible-range}@ R> - void append_range(R&& rg); - void pop_back(); - - template iterator emplace(const_iterator position, Args&&... args); - iterator insert(const_iterator position, const T& x); - iterator insert(const_iterator position, T&& x); - iterator insert(const_iterator position, size_type n, const T& x); + void insert_range(R&& rg); template - iterator insert(const_iterator position, InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range(const_iterator position, R&& rg); - iterator insert(const_iterator position, initializer_list il); + void insert(InputIterator first, InputIterator last); + void insert(size_type n, const T& x); iterator erase(const_iterator position); - iterator erase(const_iterator position, const_iterator last); - void swap(list&) noexcept(allocator_traits::is_always_equal::value); - void clear() noexcept; + iterator erase(const_iterator first, const_iterator last); + void swap(hive&) noexcept(@\seebelow@); + void clear() noexcept; - // \ref{list.ops}, list operations - void splice(const_iterator position, list& x); - void splice(const_iterator position, list&& x); - void splice(const_iterator position, list& x, const_iterator i); - void splice(const_iterator position, list&& x, const_iterator i); - void splice(const_iterator position, list& x, const_iterator first, const_iterator last); - void splice(const_iterator position, list&& x, const_iterator first, const_iterator last); + // \ref{hive.operations}, hive operations + void splice(hive& x); + void splice(hive&& x); + template> + size_type unique(BinaryPredicate binary_pred = BinaryPredicate()); - size_type remove(const T& value); - template size_type remove_if(Predicate pred); + template> + void sort(Compare comp = Compare()); - size_type unique(); - template - size_type unique(BinaryPredicate binary_pred); + iterator get_iterator(const_pointer p) noexcept; + const_iterator get_iterator(const_pointer p) const noexcept; - void merge(list& x); - void merge(list&& x); - template void merge(list& x, Compare comp); - template void merge(list&& x, Compare comp); + private: + hive_limits @\exposid{current-limits}@ = @\impdef@; // \expos + }; - void sort(); - template void sort(Compare comp); + template>> + hive(InputIterator, InputIterator, Allocator = Allocator()) + -> hive<@\exposid{iter-value-type}@, Allocator>; - void reverse() noexcept; - }; + template>> + hive(InputIterator, InputIterator, hive_limits, Allocator = Allocator()) + -> hive<@\exposid{iter-value-type}@, Allocator>; - template>> - list(InputIterator, InputIterator, Allocator = Allocator()) - -> list<@\placeholder{iter-value-type}@, Allocator>; + template>> + hive(from_range_t, R&&, Allocator = Allocator()) + -> hive, Allocator>; template>> - list(from_range_t, R&&, Allocator = Allocator()) - -> list, Allocator>; + hive(from_range_t, R&&, hive_limits, Allocator = Allocator()) + -> hive, Allocator>; } \end{codeblock} -\pnum -An incomplete type \tcode{T} may be used when instantiating \tcode{list} -if the allocator meets the -allocator completeness requirements\iref{allocator.requirements.completeness}. -\tcode{T} shall be complete before any member of the resulting specialization -of \tcode{list} is referenced. - -\rSec3[list.cons]{Constructors, copy, and assignment} +\rSec3[hive.cons]{Constructors, copy, and assignment} -\indexlibraryctor{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -explicit list(const Allocator&); +constexpr explicit hive(const Allocator&) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs an empty list, using the specified allocator. +Constructs an empty \tcode{hive}, using the specified allocator. \pnum \complexity Constant. \end{itemdescr} -\indexlibraryctor{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -explicit list(size_type n, const Allocator& = Allocator()); +constexpr hive(hive_limits block_limits, const Allocator&); \end{itemdecl} \begin{itemdescr} -\pnum -\expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. - \pnum \effects -Constructs a \tcode{list} with -\tcode{n} default-inserted elements using the specified allocator. +Constructs an empty \tcode{hive}, using the specified allocator. +Initializes \exposid{current-limits} with \tcode{block_limits}. \pnum \complexity -Linear in -\tcode{n}. +Constant. \end{itemdescr} -\indexlibraryctor{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -list(size_type n, const T& value, const Allocator& = Allocator()); +explicit hive(size_type n, const Allocator& = Allocator()); +hive(size_type n, hive_limits block_limits, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{hive}. \pnum \effects -Constructs a -\tcode{list} -with -\tcode{n} -copies of -\tcode{value}, +Constructs a \tcode{hive} with \tcode{n} default-inserted elements, using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. \pnum \complexity -Linear in -\tcode{n}. +Linear in \tcode{n}. \end{itemdescr} -\indexlibraryctor{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -template - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +hive(size_type n, const T& value, const Allocator& = Allocator()); +hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs a -\tcode{list} -equal to the range -\range{first}{last}. +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. + +\pnum +\effects +Constructs a \tcode{hive} with \tcode{n} copies of \tcode{value}, +using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. \pnum \complexity -Linear in -\tcode{distance(first, last)}. +Linear in \tcode{n}. \end{itemdescr} -\indexlibraryctor{list}% +\indexlibraryctor{hive}% +\begin{itemdecl} +template + hive(InputIterator first, InputIterator last, const Allocator& = Allocator()); +template + hive(InputIterator first, InputIterator last, hive_limits block_limits, + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{hive} equal to the range \range{first}{last}, +using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. + +\pnum +\complexity +Linear in \tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{hive}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - list(from_range_t, R&& rg, const Allocator& = Allocator()); + hive(from_range_t, R&& rg, const Allocator& = Allocator()); +template<@\exposconcept{container-compatible-range}@ R> + hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs a \tcode{list} object with the elements of the range \tcode{rg}. +Constructs a \tcode{hive} object with the elements of the range \tcode{rg}, +using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. \pnum \complexity Linear in \tcode{ranges::distance(rg)}. \end{itemdescr} -\rSec3[list.capacity]{Capacity} - -\indexlibrarymember{resize}{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -void resize(size_type sz); +hive(const hive& x); +hive(const hive& x, const type_identity_t& alloc); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. \pnum \effects -If \tcode{size() < sz}, -appends \tcode{sz - size()} default-inserted elements to the -sequence. -If \tcode{sz <= size()}, equivalent to: +Constructs a \tcode{hive} object with the elements of \tcode{x}. +If the second overload is called, uses \tcode{alloc}. +Initializes \exposid{current-limits} with \tcode{x.\exposid{current-limits}}. -\begin{codeblock} -list::iterator it = begin(); -advance(it, sz); -erase(it, end()); -\end{codeblock} +\pnum +\complexity +Linear in \tcode{x.size()}. \end{itemdescr} -\indexlibrarymember{resize}{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -void resize(size_type sz, const T& c); +hive(hive&& x); +hive(hive&& x, const type_identity_t& alloc); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{CopyInsertable} into \tcode{*this}. +For the second overload, +when \tcode{allocator_traits::is_always_equal::value} is \tcode{false}, +\tcode{T} meets the \oldconcept{MoveInsertable} requirements. \pnum \effects -As if by: -\begin{codeblock} -if (sz > size()) - insert(end(), sz-size(), c); -else if (sz < size()) { - iterator i = begin(); - advance(i, sz); - erase(i, end()); -} -else - ; // do nothing -\end{codeblock} -\end{itemdescr} - -\rSec3[list.modifiers]{Modifiers} +When the first overload is called, or +the second overload is called and +\tcode{alloc == x.get_allocator()} is \tcode{true}, +\exposid{current-limits} is set to \tcode{x.\exposid{current-limits}} and +each element block is moved from \tcode{x} into \tcode{*this}. +Pointers and references to the elements of \tcode{x} now refer to +those same elements but as members of \tcode{*this}. +Iterators referring to the elements of \tcode{x} +will continue to refer to their elements, +but they now behave as iterators into \tcode{*this}. -\indexlibrarymember{insert}{list}% -\begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); -template - iterator insert(const_iterator position, InputIterator first, - InputIterator last); -template<@\exposconcept{container-compatible-range}@ R> - iterator insert_range(const_iterator position, R&& rg); -iterator insert(const_iterator position, initializer_list); - -template reference emplace_front(Args&&... args); -template reference emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); -template<@\exposconcept{container-compatible-range}@ R> - void prepend_range(R&& rg); -void push_back(const T& x); -void push_back(T&& x); -template<@\exposconcept{container-compatible-range}@ R> - void append_range(R&& rg); -\end{itemdecl} +If the second overload is called and +\tcode{alloc == x.get_allocator()} is \tcode{false}, +each element in \tcode{x} is moved into \tcode{*this}. +References, pointers and iterators referring to the elements of \tcode{x}, as well as the past-the-end iterator of \tcode{x}, are invalidated. -\begin{itemdescr} \pnum -\complexity -Insertion of a single element into a list takes constant time and -exactly one call to a constructor of -\tcode{T}. Insertion of multiple elements into a list is linear in the -number of elements inserted, and the number of calls to the copy -constructor or move constructor of \tcode{T} is exactly equal -to the number of elements inserted. +\ensures +\tcode{x.empty()} is \tcode{true}. \pnum -\remarks -Does not affect the validity of iterators and references. -If an exception is thrown there are no effects. +\complexity +If the second overload is called and +\tcode{alloc == x.get_allocator()} is \tcode{false}, linear in \tcode{x.size()}. +Otherwise constant. \end{itemdescr} -\indexlibrarymember{erase}{list}% +\indexlibraryctor{hive}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); - -void pop_front(); -void pop_back(); -void clear() noexcept; +hive(initializer_list il, const Allocator& = Allocator()); +hive(initializer_list il, hive_limits block_limits, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Invalidates only the iterators and references to the erased elements. +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. \pnum -\throws -Nothing. +\effects +Constructs a \tcode{hive} object with the elements of \tcode{il}, +using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. \pnum \complexity -Erasing a single element is a constant time operation with a single call to the destructor of -\tcode{T}. -Erasing a range in a list is linear time in the -size of the range and the number of calls to the destructor of type -\tcode{T} -is exactly equal to the size of the range. +Linear in \tcode{il.size()}. \end{itemdescr} -\rSec3[list.ops]{Operations} - -\pnum -Since lists allow fast insertion and erasing from the middle of a list, certain -operations are provided specifically for them. -\begin{footnote} -As specified -in~\ref{allocator.requirements}, the requirements in this Clause apply only to -lists whose allocators compare equal. -\end{footnote} -In this subclause, -arguments for a template parameter -named \tcode{Predicate} or \tcode{BinaryPredicate} -shall meet the corresponding requirements in \ref{algorithms.requirements}. -The semantics of \tcode{i + n} and \tcode{i - n}, -where \tcode{i} is an iterator into the list and \tcode{n} is an integer, -are the same as those of \tcode{next(i, n)} and \tcode{prev(i, n)}, -respectively. -For \tcode{merge} and \tcode{sort}, -the definitions and requirements in \ref{alg.sorting} apply. - -\pnum -\tcode{list} provides three splice operations that destructively move elements from one list to -another. The behavior of splice operations is undefined if \tcode{get_allocator() != -x.get_allocator()}. - -\indexlibrarymember{splice}{list}% +\indexlibrarymember{operator=}{hive}% \begin{itemdecl} -void splice(const_iterator position, list& x); -void splice(const_iterator position, list&& x); +hive& operator=(const hive& x); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{addressof(x) != this} is \tcode{true}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive} and +\oldconcept{CopyAssignable}. \pnum \effects -Inserts the contents of -\tcode{x} -before -\tcode{position} -and -\tcode{x} -becomes empty. -Pointers and references to the moved elements of -\tcode{x} -now refer to those same elements but as members of -\tcode{*this}. -Iterators referring to the moved elements will continue to refer to their -elements, but they now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. - -\pnum -\throws -Nothing. +All elements in \tcode{*this} are either copy-assigned to, or destroyed. +All elements in \tcode{x} are copied into \tcode{*this}. +\begin{note} +\exposid{current-limits} is unchanged. +\end{note} \pnum \complexity -Constant time. +Linear in \tcode{size() + x.size()}. \end{itemdescr} -\indexlibrarymember{splice}{list}% +\indexlibrarymember{operator=}{hive}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator i); -void splice(const_iterator position, list&& x, const_iterator i); +hive& operator=(hive&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{i} is a valid dereferenceable iterator of \tcode{x}. +When +\begin{codeblock} +(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value) +\end{codeblock} +is \tcode{false}, +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive} and +\oldconcept{MoveAssignable}. \pnum \effects -Inserts an element pointed to by -\tcode{i} -from list -\tcode{x} -before \tcode{position} and removes the element from -\tcode{x}. -The result is unchanged if -\tcode{position == i} -or -\tcode{position == ++i}. -Pointers and references to -\tcode{*i} -continue to refer to this same element but as a member of -\tcode{*this}. -Iterators -to -\tcode{*i} -(including -\tcode{i} -itself) continue to refer to the same element, but now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. +Each element in \tcode{*this} is either move-assigned to, or destroyed. +When +\begin{codeblock} +(allocator_traits::propagate_on_container_move_assignment::value || + get_allocator() == x.get_allocator()) +\end{codeblock} +is \tcode{true}, +\exposid{current-limits} is set to \tcode{x.\exposid{current-limits}} and +each element block is moved from \tcode{x} into \tcode{*this}. +Pointers and references to the elements of \tcode{x} +now refer to those same elements but as members of \tcode{*this}. +Iterators referring to the elements of \tcode{x} +will continue to refer to their elements, +but they now behave as iterators into \tcode{*this}, not into \tcode{x}. + +When +\begin{codeblock} +(allocator_traits::propagate_on_container_move_assignment::value || + get_allocator() == x.get_allocator()) +\end{codeblock} +is \tcode{false}, +each element in \tcode{x} is moved into \tcode{*this}. +References, pointers and iterators referring to the elements of \tcode{x}, +as well as the past-the-end iterator of \tcode{x}, are invalidated. \pnum -\throws -Nothing. +\ensures +\tcode{x.empty()} is \tcode{true}. \pnum \complexity -Constant time. +Linear in \tcode{size()}. +If +\begin{codeblock} +(allocator_traits::propagate_on_container_move_assignment::value || + get_allocator() == x.get_allocator()) +\end{codeblock} +is \tcode{false}, also linear in \tcode{x.size()}. \end{itemdescr} -\indexlibrarymember{splice}{list}% +\rSec3[hive.capacity]{Capacity} + +\indexlibrarymember{capacity}{hive}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator first, - const_iterator last); -void splice(const_iterator position, list&& x, const_iterator first, - const_iterator last); +size_type capacity() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\expects -\tcode{[first, last)} is a valid range in \tcode{x}. -\tcode{position} is not an iterator in the range \range{first}{last}. - -\pnum -\effects -Inserts elements in the range -\range{first}{last} -before -\tcode{position} -and removes the elements from -\tcode{x}. -Pointers and references to the moved elements of -\tcode{x} -now refer to those same elements but as members of -\tcode{*this}. -Iterators referring to the moved elements will continue to refer to their -elements, but they now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. - -\pnum -\throws -Nothing. +\returns +The total number of elements that \tcode{*this} can hold +without requiring allocation of more element blocks. \pnum \complexity -Constant time if -\tcode{addressof(x) == this}; -otherwise, linear time. +Constant. \end{itemdescr} -\indexlibrarymember{remove}{list}% +\indexlibrarymember{reserve}{hive}% \begin{itemdecl} -size_type remove(const T& value); -template size_type remove_if(Predicate pred); +void reserve(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \effects -Erases all the elements in the list referred to by a list iterator \tcode{i} for which the -following conditions hold: \tcode{*i == value}, \tcode{pred(*i) != false}. -Invalidates only the iterators and references to the erased elements. +If \tcode{n <= capacity()} is \tcode{true}, there are no effects. +Otherwise increases \tcode{capacity()} by allocating reserved blocks. \pnum -\returns -The number of elements erased. +\ensures +\tcode{capacity() >= n} is \tcode{true}. \pnum \throws -Nothing unless an exception is thrown by -\tcode{*i == value} -or -\tcode{pred(*i) != false}. +\tcode{length_error} if \tcode{n > max_size()}, +as well as any exceptions thrown by the allocator. \pnum \complexity -Exactly -\tcode{size()} -applications of the corresponding predicate. +It does not change the size of the sequence and +takes at most linear time in the number of reserved blocks allocated. \pnum \remarks -Stable\iref{algorithm.stable}. +All references, pointers, and iterators referring to elements in \tcode{*this}, +as well as the past-the-end iterator, remain valid. \end{itemdescr} -\indexlibrarymember{unique}{list}% +\indexlibrarymember{shrink_to_fit}{hive}% \begin{itemdecl} -size_type unique(); -template size_type unique(BinaryPredicate binary_pred); +void shrink_to_fit(); \end{itemdecl} \begin{itemdescr} -\pnum -Let \tcode{binary_pred} be \tcode{equal_to<>\{\}} for the first overload. - \pnum \expects -\tcode{binary_pred} is an equivalence relation. +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive}. \pnum \effects -Erases all but the first element from every -consecutive group of equivalent elements. -That is, for a nonempty list, erases all elements referred to -by the iterator \tcode{i} in the range \range{begin() + 1}{end()} -for which \tcode{binary_pred(*i, *(i - 1))} is \tcode{true}. -Invalidates only the iterators and references to the erased elements. +\tcode{shrink_to_fit} is a non-binding request +to reduce \tcode{capacity()} to be closer to \tcode{size()}. +\begin{note} +The request is non-binding +to allow latitude for implementation-specific optimizations. +\end{note} +It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()}. +It may reallocate elements. +If \tcode{capacity()} is already equal to \tcode{size()}, there are no effects. +If an exception is thrown during allocation of a new element block, +\tcode{capacity()} may be reduced and reallocation may occur. +Otherwise if an exception is thrown, the effects are unspecified. +\pnum +\complexity +If reallocation happens, linear in the size of the sequence. + +\pnum +\remarks +If reallocation happens, +the order of the elements in \tcode{*this} may change and +all references, pointers, and iterators +referring to the elements in \tcode{*this}, +as well as the past-the-end iterator, are invalidated. +\end{itemdescr} + +\indexlibrarymember{trim_capacity}{hive}% +\begin{itemdecl} +void trim_capacity() noexcept; +void trim_capacity(size_type n) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +For the first overload, all reserved blocks are deallocated, and +\tcode{capacity()} is reduced accordingly. +For the second overload, \tcode{capacity()} is reduced to no less than \tcode{n}. + +\pnum +\complexity +Linear in the number of reserved blocks deallocated. + +\pnum +\remarks +All references, pointers, and iterators referring to elements in \tcode{*this}, +as well as the past-the-end iterator, remain valid. +\end{itemdescr} + +\indexlibrarymember{block_capacity_limits}{hive}% +\begin{itemdecl} +constexpr hive_limits block_capacity_limits() const noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum \returns -The number of elements erased. +\exposid{current-limits}. \pnum -\throws -Nothing unless an exception is thrown by the predicate. +\complexity +Constant. +\end{itemdescr} + +\indexlibrarymember{block_capacity_default_limits}{hive}% +\begin{itemdecl} +static constexpr hive_limits block_capacity_default_limits() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{hive_limits} struct +with the \tcode{min} and \tcode{max} members set to +the implementation's default limits. \pnum \complexity -If \tcode{empty()} is \tcode{false}, -exactly \tcode{size() - 1} applications of the corresponding predicate, -otherwise no applications of the predicate. +Constant. \end{itemdescr} -\indexlibrarymember{merge}{list}% +\indexlibrarymember{block_capacity_hard_limits}{hive}% \begin{itemdecl} -void merge(list& x); -void merge(list&& x); -template void merge(list& x, Compare comp); -template void merge(list&& x, Compare comp); +static constexpr hive_limits block_capacity_hard_limits() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{comp} be \tcode{less<>{}} for the first two overloads. +\returns +A \tcode{hive_limits} struct +with the \tcode{min} and \tcode{max} members set to +the implementation's hard limits. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibrarymember{reshape}{hive}% +\begin{itemdecl} +void reshape(hive_limits block_limits); +\end{itemdecl} +\begin{itemdescr} \pnum \expects -\tcode{*this} and \tcode{x} are both sorted -with respect to the comparator \tcode{comp}, and -\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive}. \pnum \effects -If \tcode{addressof(x) == this}, there are no effects. -Otherwise, merges -the two sorted ranges \range{begin()}{end()} and \range{x.begin()}{x.end()}. -The result is a range -that is sorted with respect to the comparator \tcode{comp}. -Pointers and references to the moved elements of \tcode{x} now refer to those same elements -but as members of \tcode{*this}. Iterators referring to the moved elements will continue to -refer to their elements, but they now behave as iterators into \tcode{*this}, not into -\tcode{x}. +For any active blocks not within the bounds of \tcode{block_limits}, +the elements within those active blocks are reallocated +to new or existing element blocks which are within the bounds. +Any element blocks not within the bounds of \tcode{block_limits} +are deallocated. +If an exception is thrown during allocation of a new element block, +\tcode{capacity()} may be reduced, +reallocation may occur, and +\exposid{current-limits} may be assigned +a value other than \tcode{block_limits}. +Otherwise \tcode{block_limits} is assigned to \exposid{current-limits}. +If any other exception is thrown the effects are unspecified. + +\pnum +\ensures +\tcode{size()} is unchanged. \pnum \complexity -At most \tcode{size() + x.size() - 1} comparisons -if \tcode{addressof(x) != this}; -otherwise, no comparisons are performed. +Linear in the number of element blocks in \tcode{*this}. +If reallocation happens, also linear in the number of elements reallocated. \pnum \remarks -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. +This operation may change \tcode{capacity()}. +If reallocation happens, the order of the elements in \tcode{*this} may change. +Reallocation invalidates all references, pointers, and iterators +referring to the elements in \tcode{*this}, +as well as the past-the-end iterator. +\begin{note} +If no reallocation happens, they remain valid. +\end{note} \end{itemdescr} -\indexlibrarymember{reverse}{list}% +\rSec3[hive.modifiers]{Modifiers} + +\indexlibrarymember{emplace}{hive}% \begin{itemdecl} -void reverse() noexcept; +template iterator emplace(Args&&... args); +template iterator emplace_hint(const_iterator hint, Args&&... args); \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{hive} from \tcode{args}. + \pnum \effects -Reverses the order of the elements in the list. -Does not affect the validity of iterators and references. +Inserts an object of type \tcode{T} +constructed with \tcode{std::forward(args)...}. +The \tcode{hint} parameter is ignored. +If an exception is thrown, there are no effects. +\begin{note} +\tcode{args} can directly or indirectly refer to a value in \tcode{*this}. +\end{note} + +\pnum +\returns +An iterator that points to the new element. \pnum \complexity -Linear time. +Constant. Exactly one object of type \tcode{T} is constructed. + +\pnum +\remarks +Invalidates the past-the-end iterator. \end{itemdescr} -\indexlibrarymember{sort}{list}% +\indexlibrarymember{insert}{hive}% \begin{itemdecl} -void sort(); -template void sort(Compare comp); +iterator insert(const T& x); +iterator insert(const_iterator hint, const T& x); +iterator insert(T&& x); +iterator insert(const_iterator hint, T&& x); \end{itemdecl} \begin{itemdescr} \pnum \effects -Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. -If an exception is thrown, -the order of the elements in \tcode{*this} is unspecified. -Does not affect the validity of iterators and references. +Equivalent to: \tcode{return emplace(std::forward(x));} +\begin{note} +The \tcode{hint} parameter is ignored. +\end{note} +\end{itemdescr} + +\indexlibrarymember{insert}{hive}% +\begin{itemdecl} +void insert(initializer_list rg); +template<@\exposconcept{container-compatible-range}@ R> + void insert_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceInsertable} into \tcode{hive} +from \tcode{*ranges::begin(rg)}. +\tcode{rg} and \tcode{*this} do not overlap. + +\pnum +\effects +Inserts copies of elements in \tcode{rg}. +Each iterator in the range \tcode{rg} is dereferenced exactly once. \pnum \complexity -Approximately -$N \log N$ -comparisons, where -\tcode{N == size()}. +Linear in the number of elements inserted. +Exactly one object of type \tcode{T} is constructed for each element inserted. \pnum \remarks -Stable\iref{algorithm.stable}. +If an element is inserted, invalidates the past-the-end iterator. \end{itemdescr} -\rSec3[list.erasure]{Erasure} +\indexlibrarymember{insert}{hive}% +\begin{itemdecl} +void insert(size_type n, const T& x); +\end{itemdecl} -\indexlibrarymember{erase}{list}% +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. + +\pnum +\effects +Inserts \tcode{n} copies of \tcode{x}. + +\pnum +\complexity +Linear in \tcode{n}. +Exactly one object of type \tcode{T} is constructed for each element inserted. + +\pnum +\remarks +If an element is inserted, invalidates the past-the-end iterator. +\end{itemdescr} + +\indexlibrarymember{insert}{hive}% \begin{itemdecl} -template - typename list::size_type - erase(list& c, const U& value); +template + void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return erase_if(c, [\&](auto\& elem) \{ return elem == value; \});} +Equivalent to \tcode{insert_range(ranges::subrange(first, last))}. \end{itemdescr} -\indexlibrarymember{erase_if}{list}% +\indexlibrarymember{erase}{hive}% \begin{itemdecl} -template - typename list::size_type - erase_if(list& c, Predicate pred); +iterator erase(const_iterator position); +iterator erase(const_iterator first, const_iterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\complexity +Linear in the number of elements erased. +Additionally, if any active blocks become empty of elements +as a result of the function call, +at worst linear in the number of element blocks. + +\pnum +\remarks +Invalidates references, pointers and iterators +referring to the erased elements. +An erase operation that erases the last element in \tcode{*this} +also invalidates the past-the-end iterator. +\end{itemdescr} + +\indexlibrarymember{swap}{hive}% +\begin{itemdecl} +void swap(hive& x) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return c.remove_if(pred);} +Exchanges the contents, \tcode{capacity()}, and \exposid{current-limits} +of \tcode{*this} with that of \tcode{x}. + +\pnum +\complexity +Constant. \end{itemdescr} -\rSec2[vector]{Class template \tcode{vector}} +\rSec3[hive.operations]{Operations} -\rSec3[vector.overview]{Overview} +In this subclause, +arguments for a template parameter +named \tcode{Predicate} or \tcode{BinaryPredicate} +shall meet the corresponding requirements in \ref{algorithms.requirements}. +The semantics of \tcode{i + n} and \tcode{i - n}, +where \tcode{i} is an iterator into the \tcode{hive} and \tcode{n} is an integer, +are the same as those of \tcode{next(i, n)} and \tcode{prev(i, n)}, respectively. +For \tcode{sort}, the definitions and requirements in \ref{alg.sorting} apply. + +\indexlibrarymember{splice}{hive}% +\begin{itemdecl} +void splice(hive& x); +void splice(hive&& x); +\end{itemdecl} +\begin{itemdescr} \pnum -\indexlibraryglobal{vector}% -A -\tcode{vector} -is a sequence container that supports -(amortized) constant time insert and erase operations at the end; -insert and erase in the middle take linear time. -Storage management is handled automatically, though hints can be given -to improve efficiency. +\expects +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. \pnum -A \tcode{vector} 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}, -of a sequence container, including most of the optional sequence container -requirements\iref{sequence.reqmts}, -and, for an element type other than \tcode{bool}, -of a contiguous container\iref{container.reqmts}. -The exceptions are the -\tcode{push_front}, \tcode{prepend_range}, \tcode{pop_front}, and \tcode{emplace_front} member functions, which are not -provided. Descriptions are provided here only for operations on \tcode{vector} -that are not described in one of these tables or for operations where there is -additional semantic information. +\effects +If \tcode{addressof(x) == this} is \tcode{true}, +the behavior is erroneous and there are no effects. +Otherwise, inserts the contents of \tcode{x} into \tcode{*this} and +\tcode{x} becomes empty. +Pointers and references to the moved elements of \tcode{x} +now refer to those same elements but as members of \tcode{*this}. +Iterators referring to the moved elements continue to refer to their elements, +but they now behave as iterators into \tcode{*this}, not into \tcode{x}. \pnum -The types \tcode{iterator} and \tcode{const_iterator} meet -the constexpr iterator requirements\iref{iterator.requirements.general}. +\throws +\tcode{length_error} if any of \tcode{x}'s active blocks +are not within the bounds of \exposid{current-limits}. -\begin{codeblock} -namespace std { - template> - class vector { - public: - // types - using value_type = T; - using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = @\impdefx{type of \tcode{vector::size_type}}@; // see \ref{container.requirements} - using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} - using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} - using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; +\pnum +\complexity +Linear in the sum of +all element blocks in \tcode{x} plus all element blocks in \tcode{*this}. - // \ref{vector.cons}, construct/copy/destroy - constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } - constexpr explicit vector(const Allocator&) noexcept; - constexpr explicit vector(size_type n, const Allocator& = Allocator()); - constexpr vector(size_type n, const T& value, const Allocator& = Allocator()); - template - constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); - template<@\exposconcept{container-compatible-range}@ R> - constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); - constexpr vector(const vector& x); - constexpr vector(vector&&) noexcept; - constexpr vector(const vector&, const type_identity_t&); - constexpr vector(vector&&, const type_identity_t&); - constexpr vector(initializer_list, const Allocator& = Allocator()); - constexpr ~vector(); - constexpr vector& operator=(const vector& x); - constexpr vector& operator=(vector&& x) - noexcept(allocator_traits::propagate_on_container_move_assignment::value || - allocator_traits::is_always_equal::value); - constexpr vector& operator=(initializer_list); +\pnum +\remarks +Reserved blocks in \tcode{x} are not transferred into \tcode{*this}. +If \tcode{addressof(x) == this} is \tcode{false}, +invalidates the past-the-end iterator for both \tcode{x} and \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{unique}{hive}% +\begin{itemdecl} +template> + size_type unique(BinaryPredicate binary_pred = BinaryPredicate()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{binary_pred} is an equivalence relation. + +\pnum +\effects +Erases all but the first element +from every consecutive group of equivalent elements. +That is, for a nonempty \tcode{hive}, +erases all elements referred to by the iterator \tcode{i} +in the range \range{begin() + 1}{end()} +for which \tcode{binary_pred(*i, *(i - 1))} is \tcode{true}. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by the predicate. + +\pnum +\complexity +If \tcode{empty()} is \tcode{false}, +exactly \tcode{size() - 1} applications of the corresponding predicate, +otherwise no applications of the predicate. + +\pnum +\remarks +Invalidates references, pointers, and iterators +referring to the erased elements. +If the last element in \tcode{*this} is erased, +also invalidates the past-the-end iterator. +\end{itemdescr} + +\indexlibrarymember{sort}{hive}% +\begin{itemdecl} +template> + void sort(Compare comp = Compare()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive}, +\oldconcept{MoveAssignable}, and \oldconcept{Swappable}. + +\pnum +\effects +Sorts \tcode{*this} according to the \tcode{comp} function object. +If an exception is thrown, +the order of the elements in \tcode{*this} is unspecified. + +\pnum +\complexity +\bigoh{N \log N} comparisons, where $N$ is \tcode{size()}. + +\pnum +\remarks +May allocate. +References, pointers, and iterators referring to elements in \tcode{*this}, +as well as the past-the-end iterator, may be invalidated. +\begin{note} +Not required to be stable\ref{algorithm.stable}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{get_iterator}{hive}% +\begin{itemdecl} +iterator get_iterator(const_pointer p) noexcept; +const_iterator get_iterator(const_pointer p) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{p} points to an element in \tcode{*this}. + +\pnum +\returns +An \tcode{iterator} or \tcode{const_iterator} +pointing to the same element as \tcode{p}. + +\pnum +\complexity +Linear in the number of active blocks in \tcode{*this}. +\end{itemdescr} + +\rSec3[hive.erasure]{Erasure} + +\indexlibrarymember{erase}{hive}% +\begin{itemdecl} +template + typename hive::size_type + erase(hive& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return erase_if(c, [&](auto& elem) { return elem == value; }); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{hive}% +\begin{itemdecl} +template + typename hive::size_type + erase_if(hive& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\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 + constexpr bool operator==(const list& x, const list& y); + template + constexpr @\placeholder{synth-three-way-result}@ operator<=>(const list& x, + @\itcorr@ const list& y); + + template + constexpr void swap(list& x, list& y) + noexcept(noexcept(x.swap(y))); + + // \ref{list.erasure}, erasure + template + constexpr typename list::size_type + erase(list& c, const U& value); + template + constexpr 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} + +\pnum +\indexlibraryglobal{list}% +A +\tcode{list} +is a sequence container that supports +bidirectional iterators and allows constant time insert and erase +operations anywhere within the sequence, with storage management handled +automatically. Unlike vectors\iref{vector} and deques\iref{deque}, +fast random access to list elements is not supported, but many +algorithms only need sequential access anyway. + +\pnum +A \tcode{list} 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 a sequence container, +including most of the optional sequence container +requirements\iref{sequence.reqmts}. +The exceptions are the +\tcode{operator[]} +and +\tcode{at} +member functions, which are not provided. +\begin{footnote} +These member functions +are only provided by containers whose iterators +are random access iterators. +\end{footnote} +Descriptions are provided here only for operations on +\tcode{list} +that are not described in one of these tables +or for operations where there is additional semantic information. + +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\ref{iterator.requirements.general}. + +\begin{codeblock} +namespace std { + template> + class list { + public: + // types + using value_type = T; + using allocator_type = Allocator; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = @\impdefx{type of \tcode{list::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{list::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{list::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{list::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{list.cons}, construct/copy/destroy + constexpr list() : list(Allocator()) { } + constexpr explicit list(const Allocator&); + constexpr explicit list(size_type n, const Allocator& = Allocator()); + constexpr list(size_type n, const T& value, const Allocator& = Allocator()); + template + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr list(const list& x); + constexpr list(list&& x); + constexpr list(const list&, const type_identity_t&); + constexpr list(list&&, const type_identity_t&); + constexpr list(initializer_list, const Allocator& = Allocator()); + constexpr ~list(); + constexpr list& operator=(const list& x); + constexpr list& operator=(list&& x) + noexcept(allocator_traits::is_always_equal::value); + constexpr list& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{list.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + + // element access + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{list.modifiers}, modifiers + template constexpr reference emplace_front(Args&&... args); + template constexpr reference emplace_back(Args&&... args); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator position, const_iterator last); + constexpr void swap(list&) noexcept(allocator_traits::is_always_equal::value); + constexpr void clear() noexcept; + + // \ref{list.ops}, list operations + constexpr void splice(const_iterator position, list& x); + constexpr void splice(const_iterator position, list&& x); + constexpr void splice(const_iterator position, list& x, const_iterator i); + constexpr void splice(const_iterator position, list&& x, const_iterator i); + constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); + constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); + + constexpr size_type remove(const T& value); + template constexpr size_type remove_if(Predicate pred); + + constexpr size_type unique(); + template + constexpr size_type unique(BinaryPredicate binary_pred); + + constexpr void merge(list& x); + constexpr void merge(list&& x); + template constexpr void merge(list& x, Compare comp); + template constexpr void merge(list&& x, Compare comp); + + constexpr void sort(); + template constexpr void sort(Compare comp); + + constexpr void reverse() noexcept; + }; + + template>> + list(InputIterator, InputIterator, Allocator = Allocator()) + -> list<@\placeholder{iter-value-type}@, Allocator>; + + template>> + list(from_range_t, R&&, Allocator = Allocator()) + -> list, Allocator>; +} +\end{codeblock} + +\pnum +An incomplete type \tcode{T} may be used when instantiating \tcode{list} +if the allocator meets the +allocator completeness requirements\iref{allocator.requirements.completeness}. +\tcode{T} shall be complete before any member of the resulting specialization +of \tcode{list} is referenced. + +\rSec3[list.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr explicit list(const Allocator&); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty list, using the specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr explicit list(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{list}. + +\pnum +\effects +Constructs a \tcode{list} with +\tcode{n} default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in +\tcode{n}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr list(size_type n, const T& value, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{list}. + +\pnum +\effects +Constructs a +\tcode{list} +with +\tcode{n} +copies of +\tcode{value}, +using the specified allocator. + +\pnum +\complexity +Linear in +\tcode{n}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +template + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a +\tcode{list} +equal to the range +\range{first}{last}. + +\pnum +\complexity +Linear in +\tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{list} object with the elements of the range \tcode{rg}. + +\pnum +\complexity +Linear in \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[list.capacity]{Capacity} + +\indexlibrarymember{resize}{list}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{list}. + +\pnum +\effects +If \tcode{size() < sz}, +appends \tcode{sz - size()} default-inserted elements to the +sequence. +If \tcode{sz <= size()}, equivalent to: + +\begin{codeblock} +list::iterator it = begin(); +advance(it, sz); +erase(it, end()); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{resize}{list}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{list}. + +\pnum +\effects +As if by: +\begin{codeblock} +if (sz > size()) + insert(end(), sz-size(), c); +else if (sz < size()) { + iterator i = begin(); + advance(i, sz); + erase(i, end()); +} +else + ; // do nothing +\end{codeblock} +\end{itemdescr} + +\rSec3[list.modifiers]{Modifiers} + +\indexlibrarymember{insert}{list}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_front(Args&&... args); +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\complexity +Insertion of a single element into a list takes constant time and +exactly one call to a constructor of +\tcode{T}. Insertion of multiple elements into a list is linear in the +number of elements inserted, and the number of calls to the copy +constructor or move constructor of \tcode{T} is exactly equal +to the number of elements inserted. + +\pnum +\remarks +Does not affect the validity of iterators and references. +If an exception is thrown, there are no effects. +\end{itemdescr} + +\indexlibrarymember{erase}{list}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); +constexpr void clear() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invalidates only the iterators and references to the erased elements. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Erasing a single element is a constant time operation with a single call to the destructor of +\tcode{T}. +Erasing a range in a list is linear time in the +size of the range and the number of calls to the destructor of type +\tcode{T} +is exactly equal to the size of the range. +\end{itemdescr} + +\rSec3[list.ops]{Operations} + +\pnum +Since lists allow fast insertion and erasing from the middle of a list, certain +operations are provided specifically for them. +\begin{footnote} +As specified +in~\ref{allocator.requirements}, the requirements in this Clause apply only to +lists whose allocators compare equal. +\end{footnote} +In this subclause, +arguments for a template parameter +named \tcode{Predicate} or \tcode{BinaryPredicate} +shall meet the corresponding requirements in \ref{algorithms.requirements}. +The semantics of \tcode{i + n} and \tcode{i - n}, +where \tcode{i} is an iterator into the list and \tcode{n} is an integer, +are the same as those of \tcode{next(i, n)} and \tcode{prev(i, n)}, +respectively. +For \tcode{merge} and \tcode{sort}, +the definitions and requirements in \ref{alg.sorting} apply. + +\pnum +\tcode{list} provides three splice operations that destructively move elements from one list to +another. The behavior of splice operations is undefined if \tcode{get_allocator() != +x.get_allocator()}. + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x); +constexpr void splice(const_iterator position, list&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{addressof(x) != this} is \tcode{true}. + +\pnum +\effects +Inserts the contents of +\tcode{x} +before +\tcode{position} +and +\tcode{x} +becomes empty. +Pointers and references to the moved elements of +\tcode{x} +now refer to those same elements but as members of +\tcode{*this}. +Iterators referring to the moved elements will continue to refer to their +elements, but they now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x, const_iterator i); +constexpr void splice(const_iterator position, list&& x, const_iterator i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i} is a valid dereferenceable iterator of \tcode{x}. + +\pnum +\effects +Inserts an element pointed to by +\tcode{i} +from list +\tcode{x} +before \tcode{position} and removes the element from +\tcode{x}. +The result is unchanged if +\tcode{position == i} +or +\tcode{position == ++i}. +Pointers and references to +\tcode{*i} +continue to refer to this same element but as a member of +\tcode{*this}. +Iterators +to +\tcode{*i} +(including +\tcode{i} +itself) continue to refer to the same element, but now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); +constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{first}{last} is a valid range in \tcode{x}. +\tcode{position} is not an iterator in the range \range{first}{last}. + +\pnum +\effects +Inserts elements in the range +\range{first}{last} +before +\tcode{position} +and removes the elements from +\tcode{x}. +Pointers and references to the moved elements of +\tcode{x} +now refer to those same elements but as members of +\tcode{*this}. +Iterators referring to the moved elements will continue to refer to their +elements, but they now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time if +\tcode{addressof(x) == this}; +otherwise, linear time. +\end{itemdescr} + +\indexlibrarymember{remove}{list}% +\begin{itemdecl} +constexpr size_type remove(const T& value); +template constexpr size_type remove_if(Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Erases all the elements in the list referred to by a list iterator \tcode{i} for which the +following conditions hold: \tcode{*i == value}, \tcode{pred(*i) != false}. +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by +\tcode{*i == value} +or +\tcode{pred(*i) != false}. + +\pnum +\complexity +Exactly +\tcode{size()} +applications of the corresponding predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibrarymember{unique}{list}% +\begin{itemdecl} +constexpr size_type unique(); +template constexpr size_type unique(BinaryPredicate binary_pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{binary_pred} be \tcode{equal_to<>\{\}} for the first overload. + +\pnum +\expects +\tcode{binary_pred} is an equivalence relation. + +\pnum +\effects +Erases all but the first element from every +consecutive group of equivalent elements. +That is, for a nonempty list, erases all elements referred to +by the iterator \tcode{i} in the range \range{begin() + 1}{end()} +for which \tcode{binary_pred(*i, *(i - 1))} is \tcode{true}. +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by the predicate. + +\pnum +\complexity +If \tcode{empty()} is \tcode{false}, +exactly \tcode{size() - 1} applications of the corresponding predicate, +otherwise no applications of the predicate. +\end{itemdescr} + +\indexlibrarymember{merge}{list}% +\begin{itemdecl} +constexpr void merge(list& x); +constexpr void merge(list&& x); +template constexpr void merge(list& x, Compare comp); +template constexpr void merge(list&& x, Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less<>{}} for the first two overloads. + +\pnum +\expects +\tcode{*this} and \tcode{x} are both sorted +with respect to the comparator \tcode{comp}, and +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{addressof(x) == this}, there are no effects. +Otherwise, merges +the two sorted ranges \range{begin()}{end()} and \range{x.begin()}{x.end()}. +The result is a range +that is sorted with respect to the comparator \tcode{comp}. +Pointers and references to the moved elements of \tcode{x} now refer to those same elements +but as members of \tcode{*this}. Iterators referring to the moved elements will continue to +refer to their elements, but they now behave as iterators into \tcode{*this}, not into +\tcode{x}. + +\pnum +\complexity +At most \tcode{size() + x.size() - 1} comparisons +if \tcode{addressof(x) != this}; +otherwise, no comparisons are performed. + +\pnum +\remarks +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. +\end{itemdescr} + +\indexlibrarymember{reverse}{list}% +\begin{itemdecl} +constexpr void reverse() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Reverses the order of the elements in the list. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Linear time. +\end{itemdescr} + +\indexlibrarymember{sort}{list}% +\begin{itemdecl} +void sort(); +template void sort(Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. +If an exception is thrown, +the order of the elements in \tcode{*this} is unspecified. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Approximately +$N \log N$ +comparisons, where $N$ is \tcode{size()}. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\rSec3[list.erasure]{Erasure} + +\indexlibrarymember{erase}{list}% +\begin{itemdecl} +template + typename list::size_type + constexpr erase(list& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return erase_if(c, [&](const auto& elem) -> bool { return elem == value; }); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{list}% +\begin{itemdecl} +template + typename list::size_type + constexpr erase_if(list& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +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} + +\pnum +\indexlibraryglobal{vector}% +A +\tcode{vector} +is a sequence container that supports +(amortized) constant time insert and erase operations at the end; +insert and erase in the middle take linear time. +Storage management is handled automatically, though hints can be given +to improve efficiency. + +\pnum +A \tcode{vector} 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}, +of a sequence container, including most of the optional sequence container +requirements\iref{sequence.reqmts}, +and, for an element type other than \tcode{bool}, +of a contiguous container\iref{container.reqmts}. +The exceptions are the +\tcode{push_front}, \tcode{prepend_range}, \tcode{pop_front}, and \tcode{emplace_front} member functions, which are not +provided. Descriptions are provided here only for operations on \tcode{vector} +that are not described in one of these tables or for operations where there is +additional semantic information. + +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + +\begin{codeblock} +namespace std { + template> + class vector { + public: + // types + using value_type = T; + using allocator_type = Allocator; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = @\impdefx{type of \tcode{vector::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{vector.cons}, construct/copy/destroy + constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } + constexpr explicit vector(const Allocator&) noexcept; + constexpr explicit vector(size_type n, const Allocator& = Allocator()); + constexpr vector(size_type n, const T& value, const Allocator& = Allocator()); + template + constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr vector(const vector& x); + constexpr vector(vector&&) noexcept; + constexpr vector(const vector&, const type_identity_t&); + constexpr vector(vector&&, const type_identity_t&); + constexpr vector(initializer_list, const Allocator& = Allocator()); + constexpr ~vector(); + constexpr vector& operator=(const vector& x); + constexpr vector& operator=(vector&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); + constexpr vector& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& u); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{vector.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr size_type capacity() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + constexpr void reserve(size_type n); + constexpr void shrink_to_fit(); + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{vector.data}, data access + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + + // \ref{vector.modifiers}, modifiers + template constexpr reference emplace_back(Args&&... args); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(vector&) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); + constexpr void clear() noexcept; + }; + + template>> + vector(InputIterator, InputIterator, Allocator = Allocator()) + -> vector<@\placeholder{iter-value-type}@, Allocator>; + + template>> + vector(from_range_t, R&&, Allocator = Allocator()) + -> vector, Allocator>; +} +\end{codeblock}% +\indexlibrarymember{vector}{operator==}% +\indexlibrarymember{vector}{operator<} + +\pnum +An incomplete type \tcode{T} may be used when instantiating \tcode{vector} +if the allocator meets the +allocator completeness requirements\iref{allocator.requirements.completeness}. +\tcode{T} shall be complete before any member of the resulting specialization +of \tcode{vector} is referenced. + +\rSec3[vector.cons]{Constructors} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr explicit vector(const Allocator&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{vector}, using the +specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr explicit vector(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{vector}. + +\pnum +\effects +Constructs a \tcode{vector} with \tcode{n} +default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr vector(size_type n, const T& value, + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{CopyInsertable} into \tcode{vector}. + +\pnum +\effects +Constructs a \tcode{vector} with \tcode{n} +copies of \tcode{value}, using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +template + constexpr vector(InputIterator first, InputIterator last, + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{vector} equal to the +range \range{first}{last}, using the specified allocator. + +\pnum +\complexity +Makes only $N$ +calls to the copy constructor of +\tcode{T} +(where $N$ +is the distance between +\tcode{first} +and +\tcode{last}) +and no reallocations if +\tcode{InputIterator} meets the \oldconcept{ForwardIterator} requirements. +It makes order +$N$ +calls to the copy constructor of +\tcode{T} +and order +$\log N$ +reallocations if they are just input iterators. +\end{itemdescr} + +\indexlibraryctor{vector}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{vector} object with the elements of the range \tcode{rg}, +using the specified allocator. + +\pnum +\complexity +Initializes exactly $N$ elements +from the results of dereferencing successive iterators of \tcode{rg}, +where $N$ is \tcode{ranges::distance(rg)}. + +\pnum +Performs no reallocations if: +\begin{itemize} +\item +\tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}}, and +\tcode{ranges::distance(rg) <= ranges::re\-serve_hint(rg)} is \tcode{true}, or +\item +\tcode{R} models \tcode{ranges::\libconcept{forward_range}} and +\tcode{R} does not model \tcode{ranges::\libconcept{approximately_sized_range}}. +\end{itemize} +Otherwise, performs order $\log N$ reallocations and +order $N$ calls to the copy or move constructor of \tcode{T}. +\end{itemdescr} + +\rSec3[vector.capacity]{Capacity} + +\indexlibrarymember{capacity}{vector}% +\begin{itemdecl} +constexpr size_type capacity() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The total number of elements that the vector can hold +without requiring reallocation. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{reserve}{vector}% +\begin{itemdecl} +constexpr void reserve(size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{vector}. + +\pnum +\effects +A directive that informs a +\tcode{vector} +of a planned change in size, so that it can manage the storage allocation accordingly. +After +\tcode{reserve()}, +\tcode{capacity()} +is greater or equal to the argument of +\tcode{reserve} +if reallocation happens; and equal to the previous value of +\tcode{capacity()} +otherwise. +Reallocation happens at this point if and only if the current capacity is less than the +argument of +\tcode{reserve()}. If an exception is thrown +other than by the move constructor of a non-\oldconcept{CopyInsertable} type, +there are no effects. + +\pnum +\throws +\tcode{length_error} if \tcode{n > +max_size()}. +\begin{footnote} +\tcode{reserve()} uses \tcode{Allocator::allocate()} which +can throw an appropriate exception. +\end{footnote} + +\pnum +\complexity +It does not change the size of the sequence and takes at most linear +time in the size of the sequence. + +\pnum +\remarks +Reallocation invalidates all the references, pointers, and iterators +referring to the elements in the sequence, as well as the past-the-end iterator. +\begin{note} +If no reallocation happens, they remain valid. +\end{note} +No reallocation shall take place during insertions that happen +after a call to \tcode{reserve()} +until an insertion would make the size of the vector +greater than the value of \tcode{capacity()}. +\end{itemdescr} + +\indexlibrarymember{shrink_to_fit}{vector}% +\begin{itemdecl} +constexpr void shrink_to_fit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{vector}. + +\pnum +\effects +\tcode{shrink_to_fit} is a non-binding request to reduce +\tcode{capacity()} to \tcode{size()}. +\begin{note} +The request is non-binding to allow latitude for +implementation-specific optimizations. +\end{note} +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. + +\pnum +\complexity +If reallocation happens, +linear in the size of the sequence. + +\pnum +\remarks +Reallocation invalidates all the references, pointers, and iterators +referring to the elements in the sequence as well as the past-the-end iterator. +\begin{note} +If no reallocation happens, they remain valid. +\end{note} +\end{itemdescr} + +\indexlibrarymember{swap}{vector}% +\begin{itemdecl} +constexpr void swap(vector& x) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the contents and +\tcode{capacity()} +of +\tcode{*this} +with that of \tcode{x}. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{resize}{vector}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{vector}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} default-inserted elements to the sequence. + +\pnum +\remarks +If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} +\tcode{T}, there are no effects. +\end{itemdescr} + +\indexlibrarymember{resize}{vector}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{CopyInsertable} into \tcode{vector}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} copies of \tcode{c} to the sequence. + +\pnum +\remarks +If an exception is thrown, there are no effects. +\end{itemdescr} + +\rSec3[vector.data]{Data} + +\indexlibrarymember{data}{vector}% +\begin{itemdecl} +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer such that \range{data()}{data() + size()} is a valid range. For a +non-empty vector, \tcode{data() == addressof(front())} is \keyword{true}. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\rSec3[vector.modifiers]{Modifiers} + +\indexlibrarymember{insert}{vector}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\complexity +If reallocation happens, +linear in the number of elements of the resulting vector; +otherwise, +linear in the number of elements inserted plus the distance +to the end of the vector. + +\pnum +\remarks +Causes reallocation if the new size is greater than the old capacity. +Reallocation invalidates all the references, pointers, and iterators +referring to the elements in the sequence, as well as the past-the-end iterator. +If no reallocation happens, then +references, pointers, and iterators +before the insertion point remain valid +but those at or after the insertion point, +including the past-the-end iterator, +are invalidated. +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, +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} +is \tcode{true}, there are no effects. +Otherwise, if an exception is thrown by the move constructor of a non-\oldconcept{CopyInsertable} +\tcode{T}, the effects are unspecified. + +\pnum +For the declarations taking a range \tcode{R}, +performs at most one reallocation if: +\begin{itemize} +\item +\tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}} and +\tcode{ranges::distance(rg) <= ranges::re\-serve_hint(rg)} is \tcode{true}, or +\item +\tcode{R} models \tcode{ranges::\libconcept{forward_range}} and +\tcode{R} does not model \tcode{ranges::\libconcept{approximately_sized_range}}. +\end{itemize} +For the declarations taking a pair of \tcode{InputIterator}, +performs at most one reallocation if +\tcode{InputItera\-tor} meets the \oldconcept{ForwardIterator} requirements. +\end{itemdescr} + +\indexlibrarymember{erase}{vector}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_back(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invalidates iterators and references at or after the point of the erase. + +\pnum +\throws +Nothing unless an exception is thrown by the +assignment operator or move assignment operator of +\tcode{T}. + +\pnum +\complexity +The destructor of \tcode{T} is called the number of times equal to the +number of the elements erased, but the assignment operator +of \tcode{T} is called the number of times equal to the number of +elements in the vector after the erased elements. +\end{itemdescr} + +\rSec3[vector.erasure]{Erasure} + +\indexlibrarymember{erase}{vector}% +\begin{itemdecl} +template + constexpr typename vector::size_type + erase(vector& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove(c.begin(), c.end(), value); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{vector}% +\begin{itemdecl} +template + constexpr typename vector::size_type + erase_if(vector& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove_if(c.begin(), c.end(), pred); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\rSec2[vector.bool]{Specialization of \tcode{vector} for \tcode{bool}} + +\rSec3[vector.bool.pspc]{Partial class template specialization \tcode{vector}} + +\pnum +\indexlibraryglobal{vector}% +To optimize space allocation, a partial specialization of \tcode{vector} for +\tcode{bool} elements is provided: +\begin{codeblock} +namespace std { + template + class vector { + public: + // types + using value_type = bool; + using allocator_type = Allocator; + using pointer = @\impdefx{type of \tcode{vector::pointer}}@; + using const_pointer = @\impdefx{type of \tcode{vector::const_pointer}}@; + using const_reference = bool; + using size_type = @\impdefx{type of \tcode{vector::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // bit reference + class @\libmember{reference}{vector}@ { + public: + constexpr reference(const reference&) = default; + constexpr ~reference(); + constexpr operator bool() const noexcept; + constexpr reference& operator=(bool x) noexcept; + constexpr reference& operator=(const reference& x) noexcept; + constexpr const reference& operator=(bool x) const noexcept; + constexpr void flip() noexcept; // flips the bit + }; + + // construct/copy/destroy + constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } + constexpr explicit vector(const Allocator&) noexcept; + constexpr explicit vector(size_type n, const Allocator& = Allocator()); + constexpr vector(size_type n, const bool& value, const Allocator& = Allocator()); + template + constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr vector(const vector& x); + constexpr vector(vector&& x) noexcept; + constexpr vector(const vector&, const type_identity_t&); + constexpr vector(vector&&, const type_identity_t&); + constexpr vector(initializer_list, const Allocator& = Allocator()); + constexpr ~vector(); + constexpr vector& operator=(const vector& x); + constexpr vector& operator=(vector&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); + constexpr vector& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const bool& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr size_type capacity() const noexcept; + constexpr void resize(size_type sz, bool c = false); + constexpr void reserve(size_type n); + constexpr void shrink_to_fit(); + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // modifiers + template constexpr reference emplace_back(Args&&... args); + constexpr void push_back(const bool& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const bool& x); + constexpr iterator insert(const_iterator position, size_type n, const bool& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(vector&) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); + static constexpr void swap(reference x, reference y) noexcept; + constexpr void flip() noexcept; // flips all bits + constexpr void clear() noexcept; + }; +} +\end{codeblock}% + +\pnum +Unless described below, all operations have the same requirements and +semantics as the primary \tcode{vector} template, except that operations +dealing with the \tcode{bool} value type map to bit values in the +container storage and +\tcode{allocator_traits::construct}\iref{allocator.traits.members} +is not used to construct these values. + +\pnum +There is no requirement that the data be stored as a contiguous allocation +of \tcode{bool} values. A space-optimized representation of bits is +recommended instead. + +\pnum +\tcode{reference} +is a class that simulates the behavior of references of a single bit in +\tcode{vector}. The conversion function returns \tcode{true} +when the bit is set, and \tcode{false} otherwise. The assignment operators +set the bit when the argument is (convertible to) \tcode{true} and +clear it otherwise. \tcode{flip} reverses the state of the bit. + +\indexlibrarymember{flip}{vector}% +\begin{itemdecl} +constexpr void flip() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Replaces each element in the container with its complement. +\end{itemdescr} + +\indexlibrarymember{swap}{vector}% +\begin{itemdecl} +static constexpr void swap(reference x, reference y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the contents of \tcode{x} and \tcode{y} as if by: + +\begin{codeblock} +bool b = x; +x = y; +y = b; +\end{codeblock} + +\end{itemdescr} + +\begin{itemdecl} +template struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The specialization is enabled\iref{unord.hash}. +\end{itemdescr} + +\indexlibrary{is-vector-bool-reference@\exposid{is-vector-bool-reference}}% +\begin{itemdecl} +template + constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The expression +\tcode{\exposid{is-vector-bool-reference}} is \tcode{true} +if \tcode{T} denotes the type \tcode{vector::\linebreak{}reference} +for some type \tcode{Alloc} and +\tcode{vector} is not a program-defined specialization. +\end{itemdescr} + +\rSec3[vector.bool.fmt]{Formatter specialization for \tcode{vector}} + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template + requires @\exposid{is-vector-bool-reference}@ + struct formatter { + private: + formatter @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +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} + +\pnum +\indexlibraryglobal{inplace_vector}% +An \tcode{inplace_vector} is a contiguous container. +Its capacity is fixed and +its elements are stored within the \tcode{inplace_vector} object itself. + +\pnum +An \tcode{inplace_vector} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of a contiguous container, and +of a sequence container, +including most of the optional sequence container requirements\iref{sequence.reqmts}. +The exceptions are the +\tcode{push_front}, +\tcode{prepend_range}, +\tcode{pop_front}, and +\tcode{emplace_front} +member functions, which are not provided. +Descriptions are provided here only +for operations on \tcode{inplace_vector} that +are not described in one of these tables or +for operations where there is additional semantic information. + +\pnum +For any \tcode{N}, +\tcode{inplace_vector::iterator} and +\tcode{inplace_vector::const_iterator} +meet the constexpr iterator requirements. + +\pnum +Any member function of \tcode{inplace_vector} that +would cause the size to exceed \tcode{N} +throws an exception of type \tcode{bad_alloc}. + +\pnum +Let \tcode{IV} denote a specialization of \tcode{inplace_vector}. +If \tcode{N} is zero, then +\tcode{IV} is trivially copyable and empty, and +\tcode{std::is_trivially_default_constructible_v} is \tcode{true}. +Otherwise: +\begin{itemize} +\item +If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, then +\tcode{IV} has a trivial copy constructor. +\item +If \tcode{is_trivially_move_constructible_v} is \tcode{true}, then +\tcode{IV} has a trivial move constructor. +\item +If \tcode{is_trivially_destructible_v} is \tcode{true}, then: + \begin{itemize} + \item + \tcode{IV} has a trivial destructor. + \item + If +\begin{codeblock} + is_trivially_copy_constructible_v && is_trivially_copy_assignable_v +\end{codeblock} + is \tcode{true}, then + \tcode{IV} has a trivial copy assignment operator. + \item + If +\begin{codeblock} + is_trivially_move_constructible_v && is_trivially_move_assignable_v +\end{codeblock} + is \tcode{true}, then + \tcode{IV} has a trivial move assignment operator. + \end{itemize} +\end{itemize} + +\begin{codeblock} +namespace std { + template + class inplace_vector { + public: + // types: + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{inplace_vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{inplace_vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{inplace.vector.cons}, construct/copy/destroy + constexpr inplace_vector() noexcept; + constexpr explicit inplace_vector(size_type n); // freestanding-deleted + constexpr inplace_vector(size_type n, const T& value); // freestanding-deleted template - constexpr void assign(InputIterator first, InputIterator last); + constexpr inplace_vector(InputIterator first, InputIterator last); // freestanding-deleted template<@\exposconcept{container-compatible-range}@ R> - constexpr void assign_range(R&& rg); - constexpr void assign(size_type n, const T& u); - constexpr void assign(initializer_list); - constexpr allocator_type get_allocator() const noexcept; + constexpr inplace_vector(from_range_t, R&& rg); // freestanding-deleted + constexpr inplace_vector(const inplace_vector&); + constexpr inplace_vector(inplace_vector&&) + noexcept(N == 0 || is_nothrow_move_constructible_v); + constexpr inplace_vector(initializer_list il); // freestanding-deleted + constexpr ~inplace_vector(); + constexpr inplace_vector& operator=(const inplace_vector& other); + constexpr inplace_vector& operator=(inplace_vector&& other) + noexcept(N == 0 || (is_nothrow_move_assignable_v && + is_nothrow_move_constructible_v)); + constexpr inplace_vector& operator=(initializer_list); // freestanding-deleted + template + constexpr void assign(InputIterator first, InputIterator last); // freestanding-deleted + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); // freestanding-deleted + constexpr void assign(size_type n, const T& u); // freestanding-deleted + constexpr void assign(initializer_list il); // freestanding-deleted // iterators - constexpr iterator begin() noexcept; - constexpr const_iterator begin() const noexcept; - constexpr iterator end() noexcept; - constexpr const_iterator end() const noexcept; - constexpr reverse_iterator rbegin() noexcept; - constexpr const_reverse_iterator rbegin() const noexcept; - constexpr reverse_iterator rend() noexcept; - constexpr const_reverse_iterator rend() const noexcept; - - constexpr const_iterator cbegin() const noexcept; - constexpr const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; - constexpr const_reverse_iterator crend() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; - // \ref{vector.capacity}, capacity - [[nodiscard]] constexpr bool empty() const noexcept; + // \ref{inplace.vector.capacity}, size/capacity + constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; - constexpr size_type max_size() const noexcept; - constexpr size_type capacity() const noexcept; - constexpr void resize(size_type sz); - constexpr void resize(size_type sz, const T& c); - constexpr void reserve(size_type n); - constexpr void shrink_to_fit(); + static constexpr size_type max_size() noexcept; + static constexpr size_type capacity() noexcept; + constexpr void resize(size_type sz); // freestanding-deleted + constexpr void resize(size_type sz, const T& c); // freestanding-deleted + static constexpr void reserve(size_type n); // freestanding-deleted + static constexpr void shrink_to_fit() noexcept; // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; - constexpr const_reference at(size_type n) const; - constexpr reference at(size_type n); + constexpr reference at(size_type n); // freestanding-deleted + constexpr const_reference at(size_type n) const; // freestanding-deleted constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; - // \ref{vector.data}, data access - constexpr T* data() noexcept; + // \ref{inplace.vector.data}, data access + constexpr T* data() noexcept; constexpr const T* data() const noexcept; - // \ref{vector.modifiers}, modifiers - template constexpr reference emplace_back(Args&&... args); - constexpr void push_back(const T& x); - constexpr void push_back(T&& x); + // \ref{inplace.vector.modifiers}, modifiers + template + constexpr reference emplace_back(Args&&... args); // freestanding-deleted + constexpr reference push_back(const T& x); // freestanding-deleted + constexpr reference push_back(T&& x); // freestanding-deleted template<@\exposconcept{container-compatible-range}@ R> - constexpr void append_range(R&& rg); + constexpr void append_range(R&& rg); // freestanding-deleted constexpr void pop_back(); - template constexpr iterator emplace(const_iterator position, Args&&... args); - constexpr iterator insert(const_iterator position, const T& x); - constexpr iterator insert(const_iterator position, T&& x); - constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr pointer try_emplace_back(Args&&... args); + constexpr pointer try_push_back(const T& x); + constexpr pointer try_push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr ranges::borrowed_iterator_t try_append_range(R&& rg); + + template + constexpr reference unchecked_emplace_back(Args&&... args); + constexpr reference unchecked_push_back(const T& x); + constexpr reference unchecked_push_back(T&& x); + + template + constexpr iterator emplace(const_iterator position, Args&&... args); // freestanding-deleted + constexpr iterator insert(const_iterator position, const T& x); // freestanding-deleted + constexpr iterator insert(const_iterator position, T&& x); // freestanding-deleted + constexpr iterator insert(const_iterator position, size_type n, // freestanding-deleted + const T& x); template - constexpr iterator insert(const_iterator position, + constexpr iterator insert(const_iterator position, // freestanding-deleted InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - constexpr iterator insert_range(const_iterator position, R&& rg); - constexpr iterator insert(const_iterator position, initializer_list il); + constexpr iterator insert_range(const_iterator position, R&& rg); // freestanding-deleted + constexpr iterator insert(const_iterator position, // freestanding-deleted + initializer_list il); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); - constexpr void swap(vector&) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); - constexpr void clear() noexcept; - }; - - template>> - vector(InputIterator, InputIterator, Allocator = Allocator()) - -> vector<@\placeholder{iter-value-type}@, Allocator>; + constexpr void swap(inplace_vector& x) + noexcept(N == 0 || (is_nothrow_swappable_v && + is_nothrow_move_constructible_v)); + constexpr void clear() noexcept; - template>> - vector(from_range_t, R&&, Allocator = Allocator()) - -> vector, Allocator>; + constexpr friend bool operator==(const inplace_vector& x, + const inplace_vector& y); + constexpr friend @\exposid{synth-three-way-result}@ + operator<=>(const inplace_vector& x, const inplace_vector& y); + constexpr friend void swap(inplace_vector& x, inplace_vector& y) + noexcept(N == 0 || (is_nothrow_swappable_v && + is_nothrow_move_constructible_v)) + { x.swap(y); } + }; } -\end{codeblock}% -\indexlibrarymember{vector}{operator==}% -\indexlibrarymember{vector}{operator<} - -\pnum -An incomplete type \tcode{T} may be used when instantiating \tcode{vector} -if the allocator meets the -allocator completeness requirements\iref{allocator.requirements.completeness}. -\tcode{T} shall be complete before any member of the resulting specialization -of \tcode{vector} is referenced. - -\rSec3[vector.cons]{Constructors} - -\indexlibraryctor{vector} -\begin{itemdecl} -constexpr explicit vector(const Allocator&) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an empty \tcode{vector}, using the -specified allocator. +\end{codeblock} -\pnum -\complexity -Constant. -\end{itemdescr} +\rSec3[inplace.vector.cons]{Constructors} -\indexlibraryctor{vector} +\indexlibraryctor{inplace_vector} \begin{itemdecl} -constexpr explicit vector(size_type n, const Allocator& = Allocator()); +constexpr explicit inplace_vector(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{inplace_vector}. \pnum \effects -Constructs a \tcode{vector} with \tcode{n} -default-inserted elements using the specified allocator. +Constructs an \tcode{inplace_vector} with \tcode{n} default-inserted elements. \pnum \complexity Linear in \tcode{n}. \end{itemdescr} -\indexlibraryctor{vector} +\indexlibraryctor{inplace_vector} \begin{itemdecl} -constexpr vector(size_type n, const T& value, - const Allocator& = Allocator()); +constexpr inplace_vector(size_type n, const T& value); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{T} is -\oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{inplace_vector}. \pnum \effects -Constructs a \tcode{vector} with \tcode{n} -copies of \tcode{value}, using the specified allocator. +Constructs an \tcode{inplace_vector} with \tcode{n} copies of \tcode{value}. \pnum \complexity Linear in \tcode{n}. \end{itemdescr} -\indexlibraryctor{vector} +\indexlibraryctor{inplace_vector} \begin{itemdecl} template - constexpr vector(InputIterator first, InputIterator last, - const Allocator& = Allocator()); + constexpr inplace_vector(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs a \tcode{vector} equal to the -range \range{first}{last}, using the specified allocator. +Constructs an \tcode{inplace_vector} equal to the range \range{first}{last}. \pnum \complexity -Makes only $N$ -calls to the copy constructor of -\tcode{T} -(where $N$ -is the distance between -\tcode{first} -and -\tcode{last}) -and no reallocations if iterators \tcode{first} and \tcode{last} are of forward, bidirectional, or random access categories. -It makes order -$N$ -calls to the copy constructor of -\tcode{T} -and order -$\log N$ -reallocations if they are just input iterators. +Linear in \tcode{distance(first, last)}. \end{itemdescr} -\indexlibraryctor{vector}% +\indexlibraryctor{inplace_vector} \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr inplace_vector(from_range_t, R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs a \tcode{vector} object with the elements of the range \tcode{rg}, -using the specified allocator. +Constructs an \tcode{inplace_vector} with +the elements of the range \tcode{rg}. \pnum \complexity -Initializes exactly $N$ elements -from the results of dereferencing successive iterators of \tcode{rg}, -where $N$ is \tcode{ranges::distance(rg)}. -Performs no reallocations if \tcode{R} models -\tcode{ranges::\libconcept{forward_range}} or \tcode{ranges::\libconcept{sized_range}}; -otherwise, performs order $\log N$ reallocations and -order $N$ calls to the copy or move constructor of \tcode{T}. +Linear in \tcode{ranges::distance(rg)}. \end{itemdescr} -\rSec3[vector.capacity]{Capacity} +\rSec3[inplace.vector.capacity]{Size and capacity} -\indexlibrarymember{capacity}{vector}% +\indexlibrarymember{capacity}{inplace_vector}% +\indexlibrarymember{max_size}{inplace_vector}% \begin{itemdecl} -constexpr size_type capacity() const noexcept; +static constexpr size_type capacity() noexcept; +static constexpr size_type max_size() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -The total number of elements that the vector can hold -without requiring reallocation. - -\pnum -\complexity -Constant time. -\end{itemdescr} - -\indexlibrarymember{reserve}{vector}% -\begin{itemdecl} -constexpr void reserve(size_type n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. - -\pnum -\effects -A directive that informs a -\tcode{vector} -of a planned change in size, so that it can manage the storage allocation accordingly. -After -\tcode{reserve()}, -\tcode{capacity()} -is greater or equal to the argument of -\tcode{reserve} -if reallocation happens; and equal to the previous value of -\tcode{capacity()} -otherwise. -Reallocation happens at this point if and only if the current capacity is less than the -argument of -\tcode{reserve()}. If an exception is thrown -other than by the move constructor of a non-\oldconcept{CopyInsertable} type, -there are no effects. - -\pnum -\throws -\tcode{length_error} if \tcode{n > -max_size()}. -\begin{footnote} -\tcode{reserve()} uses \tcode{Allocator::allocate()} which -can throw an appropriate exception. -\end{footnote} - -\pnum -\complexity -It does not change the size of the sequence and takes at most linear -time in the size of the sequence. - -\pnum -\remarks -Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence, as well as the past-the-end iterator. -\begin{note} -If no reallocation happens, they remain valid. -\end{note} -No reallocation shall take place during insertions that happen -after a call to \tcode{reserve()} -until an insertion would make the size of the vector -greater than the value of \tcode{capacity()}. -\end{itemdescr} - -\indexlibrarymember{shrink_to_fit}{vector}% -\begin{itemdecl} -constexpr void shrink_to_fit(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} is \oldconcept{MoveInsertable} into \tcode{*this}. - -\pnum -\effects -\tcode{shrink_to_fit} is a non-binding request to reduce -\tcode{capacity()} to \tcode{size()}. -\begin{note} -The request is non-binding to allow latitude for -implementation-specific optimizations. -\end{note} -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. - -\pnum -\complexity -If reallocation happens, -linear in the size of the sequence. - -\pnum -\remarks -Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence as well as the past-the-end iterator. -\begin{note} -If no reallocation happens, they remain valid. -\end{note} -\end{itemdescr} - -\indexlibrarymember{swap}{vector}% -\begin{itemdecl} -constexpr void swap(vector& x) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Exchanges the contents and -\tcode{capacity()} -of -\tcode{*this} -with that of \tcode{x}. - -\pnum -\complexity -Constant time. +\tcode{N}. \end{itemdescr} -\indexlibrarymember{resize}{vector}% +\indexlibrarymember{resize}{inplace_vector}% \begin{itemdecl} constexpr void resize(size_type sz); \end{itemdecl} @@ -9025,22 +11031,22 @@ \begin{itemdescr} \pnum \expects -\tcode{T} is -\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{inplace_vector}. \pnum \effects -If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements -from the sequence. Otherwise, +%FIXME: Should "is \tcode{true}" be appended here? +If \tcode{sz < size()}, +erases the last \tcode{size() - sz} elements from the sequence. +Otherwise, appends \tcode{sz - size()} default-inserted elements to the sequence. \pnum \remarks -If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} -\tcode{T} there are no effects. +If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} -\indexlibrarymember{resize}{vector}% +\indexlibrarymember{resize}{inplace_vector}% \begin{itemdecl} constexpr void resize(size_type sz, const T& c); \end{itemdecl} @@ -9048,42 +11054,47 @@ \begin{itemdescr} \pnum \expects -\tcode{T} is -\oldconcept{CopyInsertable} into \tcode{*this}. +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{inplace_vector}. \pnum \effects -If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements -from the sequence. Otherwise, +%FIXME: Should "is \tcode{true}" be appended here? +If \tcode{sz < size()}, +erases the last \tcode{size() - sz} elements from the sequence. +Otherwise, appends \tcode{sz - size()} copies of \tcode{c} to the sequence. \pnum \remarks -If an exception is thrown there are no effects. +If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} -\rSec3[vector.data]{Data} +\rSec3[inplace.vector.data]{Data} -\indexlibrarymember{data}{vector}% +\indexlibrarymember{data}{inplace_vector}% \begin{itemdecl} -constexpr T* data() noexcept; -constexpr const T* data() const noexcept; +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -A pointer such that \range{data()}{data() + size()} is a valid range. For a -non-empty vector, \tcode{data() == addressof(front())} is \keyword{true}. +A pointer such that \range{data()}{data() + size()} is a valid range. +For a non-empty \tcode{inplace_vector}, +\tcode{data() == addressof(front())} is \tcode{true}. \pnum \complexity Constant time. \end{itemdescr} -\rSec3[vector.modifiers]{Modifiers} +\rSec3[inplace.vector.modifiers]{Modifiers} -\indexlibrarymember{insert}{vector}% +\indexlibrarymember{insert}{inplace_vector}% +\indexlibrarymember{insert_range}{inplace_vector}% +\indexlibrarymember{emplace}{inplace_vector}% +\indexlibrarymember{append_range}{inplace_vector}% \begin{itemdecl} constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); @@ -9092,373 +11103,287 @@ constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> constexpr iterator insert_range(const_iterator position, R&& rg); -constexpr iterator insert(const_iterator position, initializer_list); +constexpr iterator insert(const_iterator position, initializer_list il); -template constexpr reference emplace_back(Args&&... args); -template constexpr iterator emplace(const_iterator position, Args&&... args); -constexpr void push_back(const T& x); -constexpr void push_back(T&& x); +template + constexpr iterator emplace(const_iterator position, Args&&... args); template<@\exposconcept{container-compatible-range}@ R> constexpr void append_range(R&& rg); \end{itemdecl} \begin{itemdescr} +\pnum +Let $n$ be the value of \tcode{size()} before this call for +the \tcode{append_range} overload, and +\tcode{distance(begin, position)} otherwise. + \pnum \complexity -If reallocation happens, -linear in the number of elements of the resulting vector; -otherwise, -linear in the number of elements inserted plus the distance -to the end of the vector. +Linear in the number of elements inserted plus +the distance to the end of the vector. \pnum \remarks -Causes reallocation if the new size is greater than the old capacity. -Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence, as well as the past-the-end iterator. -If no reallocation happens, then -references, pointers, and iterators -before the insertion point remain valid -but those at or after the insertion point, -including the past-the-end iterator, -are invalidated. -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 +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, 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} -is \tcode{true}, there are no effects. -Otherwise, if an exception is thrown by the move constructor of a non-\oldconcept{CopyInsertable} -\tcode{T}, the effects are unspecified. +Otherwise, +if an exception is thrown, then +$\tcode{size()} \ge n$ and +elements in the range \tcode{begin() + \range{0}{$n$}} are not modified. \end{itemdescr} -\indexlibrarymember{erase}{vector}% +\indexlibrarymember{push_back}{inplace_vector}% +\indexlibrarymember{emplace_back}{inplace_vector}% \begin{itemdecl} -constexpr iterator erase(const_iterator position); -constexpr iterator erase(const_iterator first, const_iterator last); -constexpr void pop_back(); +constexpr reference push_back(const T& x); +constexpr reference push_back(T&& x); +template + constexpr reference emplace_back(Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Invalidates iterators and references at or after the point of the erase. +\returns +\tcode{back()}. \pnum \throws -Nothing unless an exception is thrown by the -assignment operator or move assignment operator of -\tcode{T}. +\tcode{bad_alloc} or +any exception thrown by the initialization of the inserted element. \pnum \complexity -The destructor of \tcode{T} is called the number of times equal to the -number of the elements erased, but the assignment operator -of \tcode{T} is called the number of times equal to the number of -elements in the vector after the erased elements. -\end{itemdescr} - -\rSec3[vector.erasure]{Erasure} - -\indexlibrarymember{erase}{vector}% -\begin{itemdecl} -template - constexpr typename vector::size_type - erase(vector& c, const U& value); -\end{itemdecl} +Constant. -\begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -auto it = remove(c.begin(), c.end(), value); -auto r = distance(it, c.end()); -c.erase(it, c.end()); -return r; -\end{codeblock} +\remarks +If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} -\indexlibrarymember{erase_if}{vector}% +\indexlibrarymember{try_emplace_back}{inplace_vector}% +\indexlibrarymember{try_push_back}{inplace_vector}% \begin{itemdecl} -template - constexpr typename vector::size_type - erase_if(vector& c, Predicate pred); +template + constexpr pointer try_emplace_back(Args&&... args); +constexpr pointer try_push_back(const T& x); +constexpr pointer try_push_back(T&& x); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -auto it = remove_if(c.begin(), c.end(), pred); -auto r = distance(it, c.end()); -c.erase(it, c.end()); -return r; -\end{codeblock} -\end{itemdescr} - -\rSec2[vector.bool]{Specialization of \tcode{vector} for \tcode{bool}} +Let \tcode{vals} denote a pack: +\begin{itemize} +\item \tcode{std::forward(args)...} for the first overload, +\item \tcode{x} for the second overload, +\item \tcode{std::move(x)} for the third overload. +\end{itemize} -\rSec3[vector.bool.pspc]{Partial class template specialization \tcode{vector}} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{inplace_vector} from \tcode{vals...}. \pnum -\indexlibraryglobal{vector}% -To optimize space allocation, a partial specialization of \tcode{vector} for -\tcode{bool} elements is provided: -\begin{codeblock} -namespace std { - template - class vector { - public: - // types - using value_type = bool; - using allocator_type = Allocator; - using pointer = @\impdefx{type of \tcode{vector::pointer}}@; - using const_pointer = @\impdefx{type of \tcode{vector::const_pointer}}@; - using const_reference = bool; - using size_type = @\impdefx{type of \tcode{vector::size_type}}@; // see \ref{container.requirements} - using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} - using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} - using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; +\effects +If \tcode{size() < capacity()} is \tcode{true}, +appends an object of type \tcode{T} +direct-non-list-initialized with \tcode{vals...}. +Otherwise, there are no effects. - // bit reference - class @\libmember{reference}{vector}@ { - friend class vector; - constexpr reference() noexcept; +\pnum +\returns +\keyword{nullptr} if \tcode{size() == capacity()} is \tcode{true}, +otherwise \tcode{addressof(back())}. - public: - constexpr reference(const reference&) = default; - constexpr ~reference(); - constexpr operator bool() const noexcept; - constexpr reference& operator=(bool x) noexcept; - constexpr reference& operator=(const reference& x) noexcept; - constexpr const reference& operator=(bool x) const noexcept; - constexpr void flip() noexcept; // flips the bit - }; +\pnum +\throws +Nothing unless an exception is thrown by the initialization of the inserted element. - // construct/copy/destroy - constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } - constexpr explicit vector(const Allocator&) noexcept; - constexpr explicit vector(size_type n, const Allocator& = Allocator()); - constexpr vector(size_type n, const bool& value, const Allocator& = Allocator()); - template - constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); - template<@\exposconcept{container-compatible-range}@ R> - constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); - constexpr vector(const vector& x); - constexpr vector(vector&& x) noexcept; - constexpr vector(const vector&, const type_identity_t&); - constexpr vector(vector&&, const type_identity_t&); - constexpr vector(initializer_list, const Allocator& = Allocator()); - constexpr ~vector(); - constexpr vector& operator=(const vector& x); - constexpr vector& operator=(vector&& x) - noexcept(allocator_traits::propagate_on_container_move_assignment::value || - allocator_traits::is_always_equal::value); - constexpr vector& operator=(initializer_list); - template - constexpr void assign(InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@ R> - constexpr void assign_range(R&& rg); - constexpr void assign(size_type n, const bool& t); - constexpr void assign(initializer_list); - constexpr allocator_type get_allocator() const noexcept; +\pnum +\complexity +Constant. - // iterators - constexpr iterator begin() noexcept; - constexpr const_iterator begin() const noexcept; - constexpr iterator end() noexcept; - constexpr const_iterator end() const noexcept; - constexpr reverse_iterator rbegin() noexcept; - constexpr const_reverse_iterator rbegin() const noexcept; - constexpr reverse_iterator rend() noexcept; - constexpr const_reverse_iterator rend() const noexcept; +\pnum +\remarks +If an exception is thrown, there are no effects on \tcode{*this}. +\end{itemdescr} - constexpr const_iterator cbegin() const noexcept; - constexpr const_iterator cend() const noexcept; - constexpr const_reverse_iterator crbegin() const noexcept; - constexpr const_reverse_iterator crend() const noexcept; +\indexlibrarymember{try_append_range}{inplace_vector}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr ranges::borrowed_iterator_t try_append_range(R&& rg); +\end{itemdecl} - // capacity - [[nodiscard]] constexpr bool empty() const noexcept; - constexpr size_type size() const noexcept; - constexpr size_type max_size() const noexcept; - constexpr size_type capacity() const noexcept; - constexpr void resize(size_type sz, bool c = false); - constexpr void reserve(size_type n); - constexpr void shrink_to_fit(); +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{inplace_vector} from\\\tcode{*ranges::begin(rg)}. - // element access - constexpr reference operator[](size_type n); - constexpr const_reference operator[](size_type n) const; - constexpr const_reference at(size_type n) const; - constexpr reference at(size_type n); - constexpr reference front(); - constexpr const_reference front() const; - constexpr reference back(); - constexpr const_reference back() const; +\pnum +\effects +Appends copies of initial elements in \tcode{rg} before \tcode{end()}, +until all elements are inserted or \tcode{size() == capacity()} is \tcode{true}. +Each iterator in the range \tcode{rg} is dereferenced at most once. - // modifiers - template constexpr reference emplace_back(Args&&... args); - constexpr void push_back(const bool& x); - template<@\exposconcept{container-compatible-range}@ R> - constexpr void append_range(R&& rg); - constexpr void pop_back(); - template constexpr iterator emplace(const_iterator position, Args&&... args); - constexpr iterator insert(const_iterator position, const bool& x); - constexpr iterator insert(const_iterator position, size_type n, const bool& x); - template - constexpr iterator insert(const_iterator position, - InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@ R> - constexpr iterator insert_range(const_iterator position, R&& rg); - constexpr iterator insert(const_iterator position, initializer_list il); +\pnum +\returns +An iterator pointing to the first element of \tcode{rg} +that was not inserted into \tcode{*this}, +or \tcode{ranges::end(rg)} if no such element exists. - constexpr iterator erase(const_iterator position); - constexpr iterator erase(const_iterator first, const_iterator last); - constexpr void swap(vector&) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); - static constexpr void swap(reference x, reference y) noexcept; - constexpr void flip() noexcept; // flips all bits - constexpr void clear() noexcept; - }; -} -\end{codeblock}% +\pnum +\complexity +Linear in the number of elements inserted. \pnum -Unless described below, all operations have the same requirements and -semantics as the primary \tcode{vector} template, except that operations -dealing with the \tcode{bool} value type map to bit values in the -container storage and -\tcode{allocator_traits::construct}\iref{allocator.traits.members} -is not used to construct these values. +\remarks +Let $n$ be the value of \tcode{size()} prior to this call. +If an exception is thrown after the insertion of $k$ elements, then +\tcode{size()} equals $n + k$, +elements in the range \tcode{begin() + \range{0}{$n$}} are not modified, and +elements in the range \tcode{begin() + \range{$n$}{$n + k$}} correspond to +the inserted elements. +\end{itemdescr} + +\indexlibrarymember{unchecked_emplace_back}{inplace_vector}% +\begin{itemdecl} +template + constexpr reference unchecked_emplace_back(Args&&... args); +\end{itemdecl} +\begin{itemdescr} \pnum -There is no requirement that the data be stored as a contiguous allocation -of \tcode{bool} values. A space-optimized representation of bits is -recommended instead. +\expects +\tcode{size() < capacity()} is \tcode{true}. \pnum -\tcode{reference} -is a class that simulates the behavior of references of a single bit in -\tcode{vector}. The conversion function returns \tcode{true} -when the bit is set, and \tcode{false} otherwise. The assignment operators -set the bit when the argument is (convertible to) \tcode{true} and -clear it otherwise. \tcode{flip} reverses the state of the bit. +\effects +Equivalent to: +\tcode{return *try_emplace_back(std::forward(args)...);} +\end{itemdescr} -\indexlibrarymember{flip}{vector}% +\indexlibrarymember{unchecked_push_back}{inplace_vector}% \begin{itemdecl} -constexpr void flip() noexcept; +constexpr reference unchecked_push_back(const T& x); +constexpr reference unchecked_push_back(T&& x); \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{size() < capacity()} is \tcode{true}. + \pnum \effects -Replaces each element in the container with its complement. +Equivalent to: +\tcode{return *try_push_back(std::forward(x));} \end{itemdescr} -\indexlibrarymember{swap}{vector}% +\indexlibrarymember{reserve}{inplace_vector}% \begin{itemdecl} -static constexpr void swap(reference x, reference y) noexcept; +static constexpr void reserve(size_type n); \end{itemdecl} \begin{itemdescr} \pnum \effects -Exchanges the contents of \tcode{x} and \tcode{y} as if by: - -\begin{codeblock} -bool b = x; -x = y; -y = b; -\end{codeblock} +None. +\pnum +\throws +\tcode{bad_alloc} if \tcode{n > capacity()} is \tcode{true}. \end{itemdescr} +\indexlibrarymember{shrink_to_fit}{inplace_vector}% \begin{itemdecl} -template struct hash>; +static constexpr void shrink_to_fit() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -The specialization is enabled\iref{unord.hash}. +\effects +None. \end{itemdescr} -\indexlibrary{is-vector-bool-reference@\exposid{is-vector-bool-reference}}% +\indexlibrarymember{erase}{inplace_vector}% +\indexlibrarymember{pop_back}{inplace_vector}% \begin{itemdecl} -template - constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_back(); \end{itemdecl} \begin{itemdescr} \pnum -The expression -\tcode{\exposid{is-vector-bool-reference}} is \tcode{true} -if \tcode{T} denotes the type \tcode{vector::\linebreak{}reference} -for some type \tcode{Alloc} and -\tcode{vector} is not a program-defined specialization. -\end{itemdescr} - -\rSec3[vector.bool.fmt]{Formatter specialization for \tcode{vector}} +\effects +Invalidates iterators and references at or after the point of the erase. -\indexlibraryglobal{formatter}% -\begin{codeblock} -namespace std { - template - requires @\exposid{is-vector-bool-reference}@ - struct formatter { - private: - formatter @\exposid{underlying_}@; // \expos +\pnum +\throws +Nothing unless an exception is thrown by +the assignment operator or move assignment operator of \tcode{T}. - public: - template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); +\pnum +\complexity +The destructor of \tcode{T} is called the number of times +equal to the number of the elements erased, but +the assignment operator of \tcode{T} is called the number of times +equal to the number of elements after the erased elements. +\end{itemdescr} - template - typename FormatContext::iterator - format(const T& ref, FormatContext& ctx) const; - }; -} -\end{codeblock} +\rSec3[inplace.vector.erasure]{Erasure} -\indexlibrarymember{parse}{formatter}% +\indexlibrarymember{erase}{inplace_vector}% \begin{itemdecl} -template - constexpr typename ParseContext::iterator - parse(ParseContext& ctx); +template + constexpr size_t erase(inplace_vector& c, const U& value); \end{itemdecl} \begin{itemdescr} \pnum -Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\effects +Equivalent to: +\begin{codeblock} +auto it = remove(c.begin(), c.end(), value); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} \end{itemdescr} -\indexlibrarymember{format}{formatter}% +\indexlibrarymember{erase_if}{inplace_vector}% \begin{itemdecl} -template - typename FormatContext::iterator - format(const T& ref, FormatContext& ctx) const; +template + constexpr size_t erase_if(inplace_vector& c, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -Equivalent to: \tcode{return \exposid{underlying_}.format(ref, ctx);} +\effects +Equivalent to: +\begin{codeblock} +auto it = remove_if(c.begin(), c.end(), pred); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} \end{itemdescr} \rSec1[associative]{Associative containers} -\rSec2[associative.general]{In general} +\rSec2[associative.general]{General} \pnum -The header \libheader{map} defines the class templates \tcode{map} and -\tcode{multimap}; the header \libheader{set} defines the class templates +The header \libheaderrefx{map}{associative.map.syn} defines the class templates +\tcode{map} and \tcode{multimap}; +the header \libheaderrefx{set}{associative.set.syn} defines the class templates \tcode{set} and \tcode{multiset}. \pnum @@ -9502,21 +11427,21 @@ class map; template - bool operator==(const map& x, - const map& y); + constexpr bool operator==(const map& x, + const map& y); template - @\placeholder{synth-three-way-result}@> + constexpr @\placeholder{synth-three-way-result}@> operator<=>(const map& x, const map& y); template - void swap(map& x, - map& y) + constexpr void swap(map& x, + map& y) noexcept(noexcept(x.swap(y))); // \ref{map.erasure}, erasure for \tcode{map} template - typename map::size_type + constexpr typename map::size_type erase_if(map& c, Predicate pred); // \ref{multimap}, class template \tcode{multimap} @@ -9525,21 +11450,21 @@ class multimap; template - bool operator==(const multimap& x, - const multimap& y); + constexpr bool operator==(const multimap& x, + const multimap& y); template - @\placeholder{synth-three-way-result}@> + constexpr @\placeholder{synth-three-way-result}@> operator<=>(const multimap& x, const multimap& y); template - void swap(multimap& x, + constexpr void swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); // \ref{multimap.erasure}, erasure for \tcode{multimap} template - typename multimap::size_type + constexpr typename multimap::size_type erase_if(multimap& c, Predicate pred); namespace pmr { @@ -9554,66 +11479,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} @@ -9629,7 +11494,7 @@ A \tcode{map} 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 allocator-aware container\iref{container.alloc.reqmts}, and of an associative container\iref{associative.reqmts}. A \tcode{map} @@ -9658,6 +11523,10 @@ that are not described in one of those tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibrarymember{comp}{map::value_compare}% \indexlibrarymember{operator()}{map::value_compare}% \begin{codeblock} @@ -9686,177 +11555,177 @@ using insert_return_type = @\placeholdernc{insert-return-type}@; class value_compare { - friend class map; protected: Compare comp; - value_compare(Compare c) : comp(c) {} + constexpr value_compare(Compare c) : comp(c) {} public: - bool operator()(const value_type& x, const value_type& y) const { + constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // \ref{map.cons}, construct/copy/destroy - map() : map(Compare()) { } - explicit map(const Compare& comp, const Allocator& = Allocator()); + constexpr map() : map(Compare()) { } + constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); template - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); - map(const map& x); - map(map&& x); + constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); + constexpr map(const map& x); + constexpr map(map&& x); explicit map(const Allocator&); - map(const map&, const type_identity_t&); - map(map&&, const type_identity_t&); - map(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr map(const map&, const type_identity_t&); + constexpr map(map&&, const type_identity_t&); + constexpr map(initializer_list, const Compare& = Compare(), + const Allocator& = Allocator()); template - map(InputIterator first, InputIterator last, const Allocator& a) + constexpr map(InputIterator first, InputIterator last, const Allocator& a) : map(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@ R> - map(from_range_t, R&& rg, const Allocator& a)) + constexpr map(from_range_t, R&& rg, const Allocator& a)) : map(from_range, std::forward(rg), Compare(), a) { } - map(initializer_list il, const Allocator& a) + constexpr map(initializer_list il, const Allocator& a) : map(il, Compare(), a) { } - ~map(); - map& operator=(const map& x); - map& operator=(map&& x) + constexpr ~map(); + constexpr map& operator=(const map& x); + constexpr map& operator=(map&& x) noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v); - map& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr map& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{map.access}, element access - mapped_type& operator[](const key_type& x); - mapped_type& operator[](key_type&& x); - template mapped_type& operator[](K&& x); - mapped_type& at(const key_type& x); - const mapped_type& at(const key_type& x) const; - template mapped_type& at(const K& x); - template const mapped_type& at(const K& x) const; + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template constexpr mapped_type& at(const K& x); + template constexpr const mapped_type& at(const K& x) const; // \ref{map.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& x); - pair insert(value_type&& x); - template pair insert(P&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair insert(const value_type& x); + constexpr pair insert(value_type&& x); + template constexpr pair insert(P&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); template - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(map&) + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(map&) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable_v); - void clear() noexcept; + constexpr void clear() noexcept; template - void merge(map& source); + constexpr void merge(map& source); template - void merge(map&& source); + constexpr void merge(map&& source); template - void merge(multimap& source); + constexpr void merge(multimap& source); template - void merge(multimap&& source); + constexpr void merge(multimap&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; }; template>, @@ -9895,7 +11764,7 @@ \indexlibraryctor{map}% \begin{itemdecl} -explicit map(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -9913,8 +11782,8 @@ \indexlibraryctor{map}% \begin{itemdecl} template - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -9938,7 +11807,8 @@ \indexlibraryctor{map}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -9958,7 +11828,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -mapped_type& operator[](const key_type& x); +constexpr mapped_type& operator[](const key_type& x); \end{itemdecl} \begin{itemdescr} @@ -9969,7 +11839,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -mapped_type& operator[](key_type&& x); +constexpr mapped_type& operator[](key_type&& x); \end{itemdecl} \begin{itemdescr} @@ -9980,7 +11850,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -template mapped_type& operator[](K&& x); +template constexpr mapped_type& operator[](K&& x); \end{itemdecl} \begin{itemdescr} @@ -9996,8 +11866,8 @@ \indexlibrarymember{at}{map}% \begin{itemdecl} -mapped_type& at(const key_type& x); -const mapped_type& at(const key_type& x) const; +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; \end{itemdecl} \begin{itemdescr} @@ -10017,8 +11887,8 @@ \indexlibrarymember{at}{map}% \begin{itemdecl} -template mapped_type& at(const K& x); -template const mapped_type& at(const K& x) const; +template constexpr mapped_type& at(const K& x); +template constexpr const mapped_type& at(const K& x) const; \end{itemdecl} \begin{itemdescr} @@ -10050,9 +11920,9 @@ \indexlibrarymember{insert}{map}% \begin{itemdecl} template - pair insert(P&& x); + constexpr pair insert(P&& x); template - iterator insert(const_iterator position, P&& x); + constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -10070,9 +11940,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10108,9 +11978,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10146,9 +12016,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10195,9 +12065,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10235,9 +12105,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10275,9 +12145,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10326,7 +12196,7 @@ \begin{itemdecl} template typename map::size_type - erase_if(map& c, Predicate pred); + constexpr erase_if(map& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -10396,6 +12266,10 @@ that are not described in one of those tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibrarymember{comp}{multimap::value_compare}% \indexlibrarymember{operator()}{multimap::value_compare}% \begin{codeblock} @@ -10423,144 +12297,142 @@ using node_type = @\unspec@; class value_compare { - friend class multimap; protected: Compare comp; - value_compare(Compare c) : comp(c) { } + constexpr value_compare(Compare c) : comp(c) { } public: - bool operator()(const value_type& x, const value_type& y) const { + constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // \ref{multimap.cons}, construct/copy/destroy - multimap() : multimap(Compare()) { } - explicit multimap(const Compare& comp, const Allocator& = Allocator()); + constexpr multimap() : multimap(Compare()) { } + constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); template - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - multimap(from_range_t, R&& rg, - const Compare& comp = Compare(), const Allocator& = Allocator()); - multimap(const multimap& x); - multimap(multimap&& x); - explicit multimap(const Allocator&); - multimap(const multimap&, const type_identity_t&); - multimap(multimap&&, const type_identity_t&); - multimap(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr multimap(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multimap(const multimap& x); + constexpr multimap(multimap&& x); + constexpr explicit multimap(const Allocator&); + constexpr multimap(const multimap&, const type_identity_t&); + constexpr multimap(multimap&&, const type_identity_t&); + constexpr multimap(initializer_list, + const Compare& = Compare(), const Allocator& = Allocator()); template - multimap(InputIterator first, InputIterator last, const Allocator& a) + constexpr multimap(InputIterator first, InputIterator last, const Allocator& a) : multimap(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@ R> - multimap(from_range_t, R&& rg, const Allocator& a)) + constexpr multimap(from_range_t, R&& rg, const Allocator& a)) : multimap(from_range, std::forward(rg), Compare(), a) { } - multimap(initializer_list il, const Allocator& a) + constexpr multimap(initializer_list il, const Allocator& a) : multimap(il, Compare(), a) { } - ~multimap(); - multimap& operator=(const multimap& x); - multimap& operator=(multimap&& x) + constexpr ~multimap(); + constexpr multimap& operator=(const multimap& x); + constexpr multimap& operator=(multimap&& x) noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v); - multimap& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr multimap& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{multimap.modifiers}, modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x); - iterator insert(value_type&& x); - template iterator insert(P&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - template iterator insert(const_iterator position, P&& x); + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& x); + constexpr iterator insert(value_type&& x); + template constexpr iterator insert(P&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); + template constexpr iterator insert(const_iterator position, P&& x); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); template node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multimap&) + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(multimap&) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable_v); - void clear() noexcept; + constexpr void clear() noexcept; template - void merge(multimap& source); + constexpr void merge(multimap& source); template - void merge(multimap&& source); + constexpr void merge(multimap&& source); template - void merge(map& source); + constexpr void merge(map& source); template - void merge(map&& source); + constexpr void merge(map&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; }; template>, @@ -10600,7 +12472,7 @@ \indexlibraryctor{multimap}% \begin{itemdecl} -explicit multimap(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10618,9 +12490,8 @@ \indexlibraryctor{multimap}% \begin{itemdecl} template - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10645,7 +12516,8 @@ \indexlibraryctor{multimap}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multimap(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10665,8 +12537,8 @@ \indexlibrarymember{insert}{multimap}% \begin{itemdecl} -template iterator insert(P&& x); -template iterator insert(const_iterator position, P&& x); +template constexpr iterator insert(P&& x); +template constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -10687,25 +12559,86 @@ \begin{itemdecl} template typename multimap::size_type - erase_if(multimap& c, Predicate pred); + constexpr erase_if(multimap& c, Predicate pred); \end{itemdecl} -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -auto original_size = c.size(); -for (auto i = c.begin(), last = c.end(); i != last; ) { - if (pred(*i)) { - i = c.erase(i); - } else { - ++i; +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[associative.set.syn]{Header \tcode{} synopsis}% + +\indexheader{set}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{set}, class template \tcode{set} + template, class Allocator = allocator> + class set; + + template + constexpr bool operator==(const set& x, + const set& y); + template + constexpr @\placeholder{synth-three-way-result}@ operator<=>(const set& x, + @\itcorr@ const set& y); + + template + constexpr void swap(set& x, + set& y) + noexcept(noexcept(x.swap(y))); + + // \ref{set.erasure}, erasure for \tcode{set} + template + constexpr typename set::size_type + erase_if(set& c, Predicate pred); + + // \ref{multiset}, class template \tcode{multiset} + template, class Allocator = allocator> + class multiset; + + template + constexpr bool operator==(const multiset& x, + const multiset& y); + template + constexpr @\placeholder{synth-three-way-result}@ + operator<=>(const multiset& x, + const multiset& y); + + template + constexpr void swap(multiset& x, + multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{multiset.erasure}, erasure for \tcode{multiset} + template + constexpr typename multiset::size_type + erase_if(multiset& c, Predicate pred); + + namespace pmr { + template> + using set = std::set>; + + template> + using multiset = std::multiset>; } } -return original_size - c.size(); \end{codeblock} -\end{itemdescr} \rSec2[set]{Class template \tcode{set}} @@ -10725,7 +12658,7 @@ 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 allocator-aware container\iref{container.alloc.reqmts}, and of an associative container\iref{associative.reqmts}. A \tcode{set} @@ -10752,6 +12685,10 @@ that are not described in one of these tables and for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template, @@ -10778,130 +12715,132 @@ using insert_return_type = @\placeholdernc{insert-return-type}@; // \ref{set.cons}, construct/copy/destroy - set() : set(Compare()) { } - explicit set(const Compare& comp, const Allocator& = Allocator()); + constexpr set() : set(Compare()) { } + constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); template - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); - set(const set& x); - set(set&& x); - explicit set(const Allocator&); - set(const set&, const type_identity_t&); - set(set&&, const type_identity_t&); - set(initializer_list, const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr set(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(const set& x); + constexpr set(set&& x); + constexpr explicit set(const Allocator&); + constexpr set(const set&, const type_identity_t&); + constexpr set(set&&, const type_identity_t&); + constexpr set(initializer_list, + const Compare& = Compare(), const Allocator& = Allocator()); template - set(InputIterator first, InputIterator last, const Allocator& a) + constexpr set(InputIterator first, InputIterator last, const Allocator& a) : set(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@ R> - set(from_range_t, R&& rg, const Allocator& a)) + constexpr set(from_range_t, R&& rg, const Allocator& a)) : set(from_range, std::forward(rg), Compare(), a) { } - set(initializer_list il, const Allocator& a) + constexpr set(initializer_list il, const Allocator& a) : set(il, Compare(), a) { } - ~set(); - set& operator=(const set& x); - set& operator=(set&& x) + constexpr ~set(); + constexpr set& operator=(const set& x); + constexpr set& operator=(set&& x) noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v); - set& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr set& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{set.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& x); - pair insert(value_type&& x); - template pair insert(K&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - template iterator insert(const_iterator position, K&& x); + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair insert(const value_type& x); + constexpr pair insert(value_type&& x); + template constexpr pair insert(K&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); + template constexpr iterator insert(const_iterator position, K&& x); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(set&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(set&) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable_v); - void clear() noexcept; + constexpr void clear() noexcept; template - void merge(set& source); + constexpr void merge(set& source); template - void merge(set&& source); + constexpr void merge(set&& source); template - void merge(multiset& source); + constexpr void merge(multiset& source); template - void merge(multiset&& source); + constexpr void merge(multiset&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; }; template - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10982,7 +12921,8 @@ \indexlibraryctor{set}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11002,7 +12942,7 @@ \indexlibrarymember{erase_if}{set}% \begin{itemdecl} template - typename set::size_type + constexpr typename set::size_type erase_if(set& c, Predicate pred); \end{itemdecl} @@ -11027,8 +12967,8 @@ \indexlibrarymember{insert}{set}% \begin{itemdecl} -template pair insert(K&& x); -template iterator insert(const_iterator hint, K&& x); +template constexpr pair insert(K&& x); +template constexpr iterator insert(const_iterator hint, K&& x); \end{itemdecl} \begin{itemdescr} @@ -11058,7 +12998,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}. @@ -11111,6 +13051,10 @@ that are not described in one of these tables and for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template, @@ -11136,129 +13080,130 @@ using node_type = @\unspec@; // \ref{multiset.cons}, construct/copy/destroy - multiset() : multiset(Compare()) { } - explicit multiset(const Compare& comp, const Allocator& = Allocator()); + constexpr multiset() : multiset(Compare()) { } + constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); template - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@ R> - multiset(from_range_t, R&& rg, - const Compare& comp = Compare(), const Allocator& = Allocator()); - multiset(const multiset& x); - multiset(multiset&& x); - explicit multiset(const Allocator&); - multiset(const multiset&, const type_identity_t&); - multiset(multiset&&, const type_identity_t&); - multiset(initializer_list, const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr multiset(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(const multiset& x); + constexpr multiset(multiset&& x); + constexpr explicit multiset(const Allocator&); + constexpr multiset(const multiset&, const type_identity_t&); + constexpr multiset(multiset&&, const type_identity_t&); + constexpr multiset(initializer_list, const Compare& = Compare(), + const Allocator& = Allocator()); template - multiset(InputIterator first, InputIterator last, const Allocator& a) + constexpr multiset(InputIterator first, InputIterator last, const Allocator& a) : multiset(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@ R> - multiset(from_range_t, R&& rg, const Allocator& a)) + constexpr multiset(from_range_t, R&& rg, const Allocator& a)) : multiset(from_range, std::forward(rg), Compare(), a) { } - multiset(initializer_list il, const Allocator& a) + constexpr multiset(initializer_list il, const Allocator& a) : multiset(il, Compare(), a) { } - ~multiset(); - multiset& operator=(const multiset& x); - multiset& operator=(multiset&& x) + constexpr ~multiset(); + constexpr multiset& operator=(const multiset& x); + constexpr multiset& operator=(multiset&& x) noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v); - multiset& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr multiset& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x); - iterator insert(value_type&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& x); + constexpr iterator insert(value_type&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multiset&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(multiset&) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable_v); - void clear() noexcept; + constexpr void clear() noexcept; template - void merge(multiset& source); + constexpr void merge(multiset& source); template - void merge(multiset&& source); + constexpr void merge(multiset&& source); template - void merge(set& source); + constexpr void merge(set& source); template - void merge(set&& source); + constexpr void merge(set&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; }; template - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11339,7 +13284,8 @@ \indexlibraryctor{multiset}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - multiset(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11360,7 +13306,7 @@ \indexlibrarymember{erase_if}{multiset}% \begin{itemdecl} template - typename multiset::size_type + constexpr typename multiset::size_type erase_if(multiset& c, Predicate pred); \end{itemdecl} @@ -11383,13 +13329,13 @@ \rSec1[unord]{Unordered associative containers} -\rSec2[unord.general]{In general} +\rSec2[unord.general]{General} \pnum -The header \libheader{unordered_map} defines the class templates -\tcode{unordered_map} and -\tcode{unordered_multimap}; the header \libheader{unordered_set} defines the class templates -\tcode{unordered_set} and \tcode{unordered_multiset}. +The header \libheaderrefx{unordered_map}{unord.map.syn} defines the class +templates \tcode{unordered_map} and \tcode{unordered_multimap}; +the header \libheaderrefx{unordered_set}{unord.set.syn} defines the class +templates \tcode{unordered_set} and \tcode{unordered_multiset}. \pnum The exposition-only alias templates @@ -11426,31 +13372,31 @@ class unordered_multimap; template - bool operator==(const unordered_map& a, - const unordered_map& b); + constexpr bool operator==(const unordered_map& a, + const unordered_map& b); template - bool operator==(const unordered_multimap& a, - const unordered_multimap& b); + constexpr bool operator==(const unordered_multimap& a, + const unordered_multimap& b); template - void swap(unordered_map& x, - unordered_map& y) + constexpr void swap(unordered_map& x, + unordered_map& y) noexcept(noexcept(x.swap(y))); template - void swap(unordered_multimap& x, - unordered_multimap& y) + constexpr void swap(unordered_multimap& x, + unordered_multimap& y) noexcept(noexcept(x.swap(y))); // \ref{unord.map.erasure}, erasure for \tcode{unordered_map} template - typename unordered_map::size_type + constexpr typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); // \ref{unord.multimap.erasure}, erasure for \tcode{unordered_multimap} template - typename unordered_multimap::size_type + constexpr typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); namespace pmr { @@ -11473,74 +13419,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} @@ -11573,6 +13451,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_map}% \begin{codeblock} namespace std { @@ -11605,193 +13487,193 @@ using insert_return_type = @\placeholdernc{insert-return-type}@; // \ref{unord.map.cnstr}, construct/copy/destroy - unordered_map(); - explicit unordered_map(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(); + constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template - unordered_map(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_map(from_range_t, R&& rg, size_type n = @\seebelow@, + constexpr unordered_map(from_range_t, R&& rg, size_type n = @\seebelow@, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_map(const unordered_map&); - unordered_map(unordered_map&&); - explicit unordered_map(const Allocator&); - unordered_map(const unordered_map&, const type_identity_t&); - unordered_map(unordered_map&&, const type_identity_t&); - unordered_map(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_map(size_type n, const allocator_type& a) + constexpr unordered_map(const unordered_map&); + constexpr unordered_map(unordered_map&&); + constexpr explicit unordered_map(const Allocator&); + constexpr unordered_map(const unordered_map&, const type_identity_t&); + constexpr unordered_map(unordered_map&&, const type_identity_t&); + constexpr unordered_map(initializer_list il, size_type n = @\seebelow@, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_map(size_type n, const allocator_type& a) : unordered_map(n, hasher(), key_equal(), a) { } - unordered_map(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_map(size_type n, const hasher& hf, const allocator_type& a) : unordered_map(n, hf, key_equal(), a) { } template - unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_map(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_map(f, l, n, hasher(), key_equal(), a) { } template - unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + constexpr unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hf, key_equal(), a) { } - unordered_map(initializer_list il, size_type n, const allocator_type& a) + constexpr unordered_map(initializer_list il, size_type n, + const allocator_type& a) : unordered_map(il, n, hasher(), key_equal(), a) { } - unordered_map(initializer_list il, size_type n, const hasher& hf, + constexpr unordered_map(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(il, n, hf, key_equal(), a) { } - ~unordered_map(); - unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&) + constexpr ~unordered_map(); + constexpr unordered_map& operator=(const unordered_map&); + constexpr unordered_map& operator=(unordered_map&&) noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v && is_nothrow_move_assignable_v); - unordered_map& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + constexpr unordered_map& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.map.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& obj); - pair insert(value_type&& obj); - template pair insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template iterator insert(const_iterator hint, P&& obj); - template void insert(InputIterator first, InputIterator last); + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair insert(const value_type& obj); + constexpr pair insert(value_type&& obj); + template constexpr pair insert(P&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template constexpr iterator insert(const_iterator hint, P&& obj); + template constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_map&) + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_map&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_swappable_v && - is_nothrow_swappable_v); - void clear() noexcept; + is_nothrow_swappable_v && is_nothrow_swappable_v); + constexpr void clear() noexcept; template - void merge(unordered_map& source); + constexpr void merge(unordered_map& source); template - void merge(unordered_map&& source); + constexpr void merge(unordered_map&& source); template - void merge(unordered_multimap& source); + constexpr void merge(unordered_multimap& source); template - void merge(unordered_multimap&& source); + constexpr void merge(unordered_multimap&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template - iterator find(const K& k); + constexpr iterator find(const K& k); template - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template - bool contains(const K& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair equal_range(const key_type& k); + constexpr pair equal_range(const key_type& k) const; template - pair equal_range(const K& k); + constexpr pair equal_range(const K& k); template - pair equal_range(const K& k) const; + constexpr pair equal_range(const K& k) const; // \ref{unord.map.elem}, element access - mapped_type& operator[](const key_type& k); - mapped_type& operator[](key_type&& k); - template mapped_type& operator[](K&& k); - mapped_type& at(const key_type& k); - const mapped_type& at(const key_type& k) const; - template mapped_type& at(const K& k); - template const mapped_type& at(const K& k) const; + constexpr mapped_type& operator[](const key_type& k); + constexpr mapped_type& operator[](key_type&& k); + template constexpr mapped_type& operator[](K&& k); + constexpr mapped_type& at(const key_type& k); + constexpr const mapped_type& at(const key_type& k) const; + template constexpr mapped_type& at(const K& k); + template constexpr const mapped_type& at(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template - unordered_map(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_map(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_map(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_map(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -11938,7 +13816,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& operator[](const key_type& k); +constexpr mapped_type& operator[](const key_type& k); \end{itemdecl} \begin{itemdescr} @@ -11950,7 +13828,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& operator[](key_type&& k); +constexpr mapped_type& operator[](key_type&& k); \end{itemdecl} \begin{itemdescr} @@ -11962,7 +13840,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -template mapped_type& operator[](K&& k); +template constexpr mapped_type& operator[](K&& k); \end{itemdecl} \begin{itemdescr} @@ -11979,8 +13857,8 @@ \indexlibrarymember{unordered_map}{at}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& at(const key_type& k); -const mapped_type& at(const key_type& k) const; +constexpr mapped_type& at(const key_type& k); +constexpr const mapped_type& at(const key_type& k) const; \end{itemdecl} \begin{itemdescr} @@ -11996,8 +13874,8 @@ \indexlibrarymember{unordered_map}{at}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -template mapped_type& at(const K& k); -template const mapped_type& at(const K& k) const; +template constexpr mapped_type& at(const K& k); +template constexpr const mapped_type& at(const K& k) const; \end{itemdecl} \begin{itemdescr} @@ -12025,7 +13903,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} template - pair insert(P&& obj); + constexpr pair insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12042,7 +13920,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} template - iterator insert(const_iterator hint, P&& obj); + constexpr iterator insert(const_iterator hint, P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12059,9 +13937,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12097,9 +13975,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12135,9 +14013,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12184,9 +14062,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12224,9 +14102,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12264,9 +14142,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12315,7 +14193,7 @@ \indexlibrarymember{erase_if}{unordered_map}% \begin{itemdecl} template - typename unordered_map::size_type + constexpr typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); \end{itemdecl} @@ -12368,6 +14246,10 @@ that are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multimap}% \begin{codeblock} namespace std { @@ -12399,162 +14281,159 @@ using node_type = @\unspec@; // \ref{unord.multimap.cnstr}, construct/copy/destroy - unordered_multimap(); - explicit unordered_multimap(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(); + constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template - unordered_multimap(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_multimap(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(const unordered_multimap&); - unordered_multimap(unordered_multimap&&); - explicit unordered_multimap(const Allocator&); - unordered_multimap(const unordered_multimap&, const type_identity_t&); - unordered_multimap(unordered_multimap&&, const type_identity_t&); - unordered_multimap(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(size_type n, const allocator_type& a) + constexpr unordered_multimap(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multimap(const unordered_multimap&); + constexpr unordered_multimap(unordered_multimap&&); + constexpr explicit unordered_multimap(const Allocator&); + constexpr unordered_multimap(const unordered_multimap&, const type_identity_t&); + constexpr unordered_multimap(unordered_multimap&&, const type_identity_t&); + constexpr unordered_multimap(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multimap(size_type n, const allocator_type& a) : unordered_multimap(n, hasher(), key_equal(), a) { } - unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(n, hf, key_equal(), a) { } template - unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_multimap(f, l, n, hasher(), key_equal(), a) { } template - unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const allocator_type& a) : unordered_multimap(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, + constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hf, key_equal(), a) { } - unordered_multimap(initializer_list il, size_type n, const allocator_type& a) + constexpr unordered_multimap(initializer_list il, size_type n, + const allocator_type& a) : unordered_multimap(il, n, hasher(), key_equal(), a) { } - unordered_multimap(initializer_list il, size_type n, const hasher& hf, + constexpr unordered_multimap(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(il, n, hf, key_equal(), a) { } - ~unordered_multimap(); - unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&) + constexpr ~unordered_multimap(); + constexpr unordered_multimap& operator=(const unordered_multimap&); + constexpr unordered_multimap& operator=(unordered_multimap&&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable_v && - is_nothrow_move_assignable_v); - unordered_multimap& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v && is_nothrow_move_assignable_v); + constexpr unordered_multimap& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.multimap.modifiers}, modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - iterator insert(value_type&& obj); - template iterator insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template iterator insert(const_iterator hint, P&& obj); - template void insert(InputIterator first, InputIterator last); + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& obj); + constexpr iterator insert(value_type&& obj); + template constexpr iterator insert(P&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template constexpr iterator insert(const_iterator hint, P&& obj); + template constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); - - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_multimap&) + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); + + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_multimap&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_swappable_v && - is_nothrow_swappable_v); - void clear() noexcept; + is_nothrow_swappable_v && is_nothrow_swappable_v); + constexpr void clear() noexcept; template - void merge(unordered_multimap& source); + constexpr void merge(unordered_multimap& source); template - void merge(unordered_multimap&& source); + constexpr void merge(unordered_multimap&& source); template - void merge(unordered_map& source); + constexpr void merge(unordered_map& source); template - void merge(unordered_map&& source); + constexpr void merge(unordered_map&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template - iterator find(const K& k); + constexpr iterator find(const K& k); template - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template - bool contains(const K& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair equal_range(const key_type& k); + constexpr pair equal_range(const key_type& k) const; template - pair equal_range(const K& k); + constexpr pair equal_range(const K& k); template - pair equal_range(const K& k) const; + constexpr pair equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template - unordered_multimap(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_multimap(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_multimap(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_multimap(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -12704,7 +14579,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} template - iterator insert(P&& obj); + constexpr iterator insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12720,7 +14595,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} template - iterator insert(const_iterator hint, P&& obj); + constexpr iterator insert(const_iterator hint, P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12739,7 +14614,7 @@ \indexlibrarymember{erase_if}{unordered_multimap}% \begin{itemdecl} template - typename unordered_multimap::size_type + constexpr typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); \end{itemdecl} @@ -12760,6 +14635,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 + constexpr bool operator==(const unordered_set& a, + const unordered_set& b); + + template + constexpr bool operator==(const unordered_multiset& a, + const unordered_multiset& b); + + template + constexpr void swap(unordered_set& x, + unordered_set& y) + noexcept(noexcept(x.swap(y))); + + template + constexpr void swap(unordered_multiset& x, + unordered_multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} + template + constexpr typename unordered_set::size_type + erase_if(unordered_set& c, Predicate pred); + + // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} + template + constexpr 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} @@ -12793,6 +14736,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_set}% \begin{codeblock} namespace std { @@ -12823,161 +14770,159 @@ using insert_return_type = @\placeholdernc{insert-return-type}@; // \ref{unord.set.cnstr}, construct/copy/destroy - unordered_set(); - explicit unordered_set(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(); + constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template - unordered_set(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_set(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_set(const unordered_set&); - unordered_set(unordered_set&&); - explicit unordered_set(const Allocator&); - unordered_set(const unordered_set&, const type_identity_t&); - unordered_set(unordered_set&&, const type_identity_t&); - unordered_set(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_set(size_type n, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_set(const unordered_set&); + constexpr unordered_set(unordered_set&&); + constexpr explicit unordered_set(const Allocator&); + constexpr unordered_set(const unordered_set&, const type_identity_t&); + constexpr unordered_set(unordered_set&&, const type_identity_t&); + constexpr unordered_set(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_set(size_type n, const allocator_type& a) : unordered_set(n, hasher(), key_equal(), a) { } - unordered_set(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_set(size_type n, const hasher& hf, const allocator_type& a) : unordered_set(n, hf, key_equal(), a) { } template - unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_set(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_set(f, l, n, hasher(), key_equal(), a) { } template - unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(f, l, n, hf, key_equal(), a) { } - unordered_set(initializer_list il, size_type n, const allocator_type& a) + constexpr unordered_set(initializer_list il, size_type n, + const allocator_type& a) : unordered_set(il, n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hf, key_equal(), a) { } - unordered_set(initializer_list il, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_set(initializer_list il, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(il, n, hf, key_equal(), a) { } - ~unordered_set(); - unordered_set& operator=(const unordered_set&); - unordered_set& operator=(unordered_set&&) + constexpr ~unordered_set(); + constexpr unordered_set& operator=(const unordered_set&); + constexpr unordered_set& operator=(unordered_set&&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable_v && - is_nothrow_move_assignable_v); - unordered_set& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v && is_nothrow_move_assignable_v); + constexpr unordered_set& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.set.modifiers}, modifiers - template pair emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& obj); - pair insert(value_type&& obj); - template pair insert(K&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template iterator insert(const_iterator hint, K&& obj); - template void insert(InputIterator first, InputIterator last); + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair insert(const value_type& obj); + constexpr pair insert(value_type&& obj); + template constexpr pair insert(K&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template constexpr iterator insert(const_iterator hint, K&& obj); + template constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_set&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_set&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_swappable_v && - is_nothrow_swappable_v); - void clear() noexcept; + is_nothrow_swappable_v && is_nothrow_swappable_v); + constexpr void clear() noexcept; template - void merge(unordered_set& source); + constexpr void merge(unordered_set& source); template - void merge(unordered_set&& source); + constexpr void merge(unordered_set&& source); template - void merge(unordered_multiset& source); + constexpr void merge(unordered_multiset& source); template - void merge(unordered_multiset&& source); + constexpr void merge(unordered_multiset&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template - iterator find(const K& k); + constexpr iterator find(const K& k); template - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template - bool contains(const K& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair equal_range(const key_type& k); + constexpr pair equal_range(const key_type& k) const; template - pair equal_range(const K& k); + constexpr pair equal_range(const K& k); template - pair equal_range(const K& k) const; + constexpr pair equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template - unordered_set(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_set(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_set(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13116,7 +15057,7 @@ \indexlibrarymember{erase_if}{unordered_set}% \begin{itemdecl} template - typename unordered_set::size_type + constexpr typename unordered_set::size_type erase_if(unordered_set& c, Predicate pred); \end{itemdecl} @@ -13141,8 +15082,8 @@ \indexlibrarymember{insert}{unordered_set}% \begin{itemdecl} -template pair insert(K&& obj); -template iterator insert(const_iterator hint, K&& obj); +template constexpr pair insert(K&& obj); +template constexpr iterator insert(const_iterator hint, K&& obj); \end{itemdecl} \begin{itemdescr} @@ -13215,6 +15156,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multiset}% \begin{codeblock} namespace std { @@ -13244,161 +15189,158 @@ using node_type = @\unspec@; // \ref{unord.multiset.cnstr}, construct/copy/destroy - unordered_multiset(); - explicit unordered_multiset(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(); + constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template - unordered_multiset(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multiset(const unordered_multiset&); - unordered_multiset(unordered_multiset&&); - explicit unordered_multiset(const Allocator&); - unordered_multiset(const unordered_multiset&, const type_identity_t&); - unordered_multiset(unordered_multiset&&, const type_identity_t&); - unordered_multiset(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multiset(size_type n, const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multiset(const unordered_multiset&); + constexpr unordered_multiset(unordered_multiset&&); + constexpr explicit unordered_multiset(const Allocator&); + constexpr unordered_multiset(const unordered_multiset&, const type_identity_t&); + constexpr unordered_multiset(unordered_multiset&&, const type_identity_t&); + constexpr unordered_multiset(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multiset(size_type n, const allocator_type& a) : unordered_multiset(n, hasher(), key_equal(), a) { } - unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(n, hf, key_equal(), a) { } template - unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_multiset(f, l, n, hasher(), key_equal(), a) { } template - unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const allocator_type& a) : unordered_multiset(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@ R> - unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hf, key_equal(), a) { } - unordered_multiset(initializer_list il, size_type n, const allocator_type& a) + constexpr unordered_multiset(initializer_list il, size_type n, + const allocator_type& a) : unordered_multiset(il, n, hasher(), key_equal(), a) { } - unordered_multiset(initializer_list il, size_type n, const hasher& hf, + constexpr unordered_multiset(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(il, n, hf, key_equal(), a) { } - ~unordered_multiset(); - unordered_multiset& operator=(const unordered_multiset&); - unordered_multiset& operator=(unordered_multiset&&) + constexpr ~unordered_multiset(); + constexpr unordered_multiset& operator=(const unordered_multiset&); + constexpr unordered_multiset& operator=(unordered_multiset&&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable_v && - is_nothrow_move_assignable_v); - unordered_multiset& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v && is_nothrow_move_assignable_v); + constexpr unordered_multiset& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template iterator emplace(Args&&... args); - template iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - iterator insert(value_type&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template void insert(InputIterator first, InputIterator last); + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& obj); + constexpr iterator insert(value_type&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); - void insert(initializer_list); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_multiset&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_multiset&) noexcept(allocator_traits::is_always_equal::value && - is_nothrow_swappable_v && - is_nothrow_swappable_v); - void clear() noexcept; + is_nothrow_swappable_v && is_nothrow_swappable_v); + constexpr void clear() noexcept; template - void merge(unordered_multiset& source); + constexpr void merge(unordered_multiset& source); template - void merge(unordered_multiset&& source); + constexpr void merge(unordered_multiset&& source); template - void merge(unordered_set& source); + constexpr void merge(unordered_set& source); template - void merge(unordered_set&& source); + constexpr void merge(unordered_set&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template - iterator find(const K& k); + constexpr iterator find(const K& k); template - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template - bool contains(const K& k) const; - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair equal_range(const key_type& k); + constexpr pair equal_range(const key_type& k) const; template - pair equal_range(const K& k); + constexpr pair equal_range(const K& k); template - pair equal_range(const K& k) const; + constexpr pair equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template - unordered_multiset(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@ R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_multiset(initializer_list il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_multiset(initializer_list il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13537,7 +15475,7 @@ \indexlibrarymember{erase_if}{unordered_multiset}% \begin{itemdecl} template - typename unordered_multiset::size_type + constexpr typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); \end{itemdecl} @@ -13560,14 +15498,14 @@ \rSec1[container.adaptors]{Container adaptors} -\rSec2[container.adaptors.general]{In general} +\rSec2[container.adaptors.general]{General} \pnum The headers -\libheader{queue}, -\libheader{stack}, -\libheader{flat_map}, -and \libheader{flat_set} +\libheaderref{queue}, +\libheaderref{stack}, +\libheaderrefx{flat_map}{flat.map.syn}, +and \libheaderrefx{flat_set}{flat.set.syn} define the container adaptors \tcode{queue} and \tcode{priority_queue}, \tcode{stack}, @@ -13631,8 +15569,8 @@ \item It has both \tcode{KeyContainer} and \tcode{Compare} template parameters, and \begin{codeblock} is_invocable_v + const typename KeyContainer::value_type&, + const typename KeyContainer::value_type&> \end{codeblock} is not a valid expression or is \tcode{false}. \item It has both \tcode{MappedContainer} and \tcode{Allocator} template parameters, and @@ -13668,23 +15606,24 @@ template> class queue; template - bool operator==(const queue& x, const queue& y); + constexpr bool operator==(const queue& x, const queue& y); template - bool operator!=(const queue& x, const queue& y); + constexpr bool operator!=(const queue& x, const queue& y); template - bool operator< (const queue& x, const queue& y); + constexpr bool operator< (const queue& x, const queue& y); template - bool operator> (const queue& x, const queue& y); + constexpr bool operator> (const queue& x, const queue& y); template - bool operator<=(const queue& x, const queue& y); + constexpr bool operator<=(const queue& x, const queue& y); template - bool operator>=(const queue& x, const queue& y); + constexpr bool operator>=(const queue& x, const queue& y); template - compare_three_way_result_t + constexpr compare_three_way_result_t operator<=>(const queue& x, const queue& y); template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(queue& x, queue& y) + noexcept(noexcept(x.swap(y))); template struct uses_allocator, Alloc>; @@ -13698,8 +15637,8 @@ class priority_queue; template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(priority_queue& x, + priority_queue& y) noexcept(noexcept(x.swap(y))); template struct uses_allocator, Alloc>; @@ -13709,132 +15648,6 @@ } \end{codeblock} -\rSec2[stack.syn]{Header \tcode{} synopsis} - -\indexheader{stack}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{stack}, class template \tcode{stack} - template> class stack; - - template - bool operator==(const stack& x, const stack& y); - template - bool operator!=(const stack& x, const stack& y); - template - bool operator< (const stack& x, const stack& y); - template - bool operator> (const stack& x, const stack& y); - template - bool operator<=(const stack& x, const stack& y); - template - bool operator>=(const stack& x, const stack& y); - template - compare_three_way_result_t - operator<=>(const stack& x, const stack& y); - - template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); - template - struct uses_allocator, Alloc>; - - // \ref{container.adaptors.format}, formatter specialization for \tcode{stack} - template Container> - struct formatter, charT>; -} -\end{codeblock} - -\rSec2[flat.map.syn]{Header \tcode{} synopsis} - -\indexheader{flat_map}% -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{flat.map}, class template \tcode{flat_map} - template, - class KeyContainer = vector, class MappedContainer = vector> - class flat_map; - - struct sorted_unique_t { explicit sorted_unique_t() = default; }; - inline constexpr sorted_unique_t sorted_unique{}; - - template - struct uses_allocator, - Allocator>; - - // \ref{flat.map.erasure}, erasure for \tcode{flat_map} - template - typename flat_map::size_type - erase_if(flat_map& c, Predicate pred); - - // \ref{flat.multimap}, class template \tcode{flat_multimap} - template, - class KeyContainer = vector, class MappedContainer = vector> - class flat_multimap; - - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; - - template - struct uses_allocator, - Allocator>; - - // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} - template - typename flat_multimap::size_type - erase_if(flat_multimap& c, Predicate pred); -} -\end{codeblock} - -\rSec2[flat.set.syn]{Header \tcode{} synopsis}% -\indexheader{flat_set}% - -\begin{codeblock} -#include // see \ref{compare.syn} -#include // see \ref{initializer.list.syn} - -namespace std { - // \ref{flat.set}, class template \tcode{flat_set} - template, class KeyContainer = vector> - class flat_set; - - struct sorted_unique_t { explicit sorted_unique_t() = default; }; - inline constexpr sorted_unique_t sorted_unique{}; - - template - struct uses_allocator, Allocator>; - - // \ref{flat.set.erasure}, erasure for \tcode{flat_set} - template - typename flat_set::size_type - erase_if(flat_set& c, Predicate pred); - - // \ref{flat.multiset}, class template \tcode{flat_multiset} - template, class KeyContainer = vector> - class flat_multiset; - - struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; - inline constexpr sorted_equivalent_t sorted_equivalent{}; - - template - struct uses_allocator, Allocator>; - - // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} - template - typename flat_multiset::size_type - erase_if(flat_multiset& c, Predicate pred); -} -\end{codeblock} - \rSec2[queue]{Class template \tcode{queue}} \rSec3[queue.defn]{Definition} @@ -13870,35 +15683,35 @@ Container c; public: - queue() : queue(Container()) {} - explicit queue(const Container&); - explicit queue(Container&&); - template queue(InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@ R> queue(from_range_t, R&& rg); - template explicit queue(const Alloc&); - template queue(const Container&, const Alloc&); - template queue(Container&&, const Alloc&); - template queue(const queue&, const Alloc&); - template queue(queue&&, const Alloc&); + constexpr queue() : queue(Container()) {} + constexpr explicit queue(const Container&); + constexpr explicit queue(Container&&); + template constexpr queue(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> constexpr queue(from_range_t, R&& rg); + template constexpr explicit queue(const Alloc&); + template constexpr queue(const Container&, const Alloc&); + template constexpr queue(Container&&, const Alloc&); + template constexpr queue(const queue&, const Alloc&); + template constexpr queue(queue&&, const Alloc&); template - queue(InputIterator first, InputIterator last, const Alloc&); + constexpr queue(InputIterator first, InputIterator last, const Alloc&); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - queue(from_range_t, R&& rg, const Alloc&); - - [[nodiscard]] bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference front() { return c.front(); } - const_reference front() const { return c.front(); } - reference back() { return c.back(); } - const_reference back() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void push(value_type&& x) { c.push_back(std::move(x)); } - template<@\exposconcept{container-compatible-range}@ R> void push_range(R&& rg); + constexpr queue(from_range_t, R&& rg, const Alloc&); + + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr reference front() { return c.front(); } + constexpr const_reference front() const { return c.front(); } + constexpr reference back() { return c.back(); } + constexpr const_reference back() const { return c.back(); } + constexpr void push(const value_type& x) { c.push_back(x); } + constexpr void push(value_type&& x) { c.push_back(std::move(x)); } + template<@\exposconcept{container-compatible-range}@ R> constexpr void push_range(R&& rg); template - decltype(auto) emplace(Args&&... args) + constexpr decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward(args)...); } - void pop() { c.pop_front(); } - void swap(queue& q) noexcept(is_nothrow_swappable_v) + constexpr void pop() { c.pop_front(); } + constexpr void swap(queue& q) noexcept(is_nothrow_swappable_v) { using std::swap; swap(c, q.c); } }; @@ -13933,7 +15746,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(const Container& cont); +constexpr explicit queue(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -13944,7 +15757,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(Container&& cont); +constexpr explicit queue(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -13956,7 +15769,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template - queue(InputIterator first, InputIterator last); + constexpr queue(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -13969,7 +15782,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - queue(from_range_t, R&& rg); + constexpr queue(from_range_t, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -13986,7 +15799,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template explicit queue(const Alloc& a); +template constexpr explicit queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -13997,7 +15810,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template queue(const container_type& cont, const Alloc& a); +template constexpr queue(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14009,7 +15822,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template queue(container_type&& cont, const Alloc& a); +template constexpr queue(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14021,7 +15834,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template queue(const queue& q, const Alloc& a); +template constexpr queue(const queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14033,7 +15846,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template queue(queue&& q, const Alloc& a); +template constexpr queue(queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14046,7 +15859,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template - queue(InputIterator first, InputIterator last, const Alloc& alloc); + constexpr queue(InputIterator first, InputIterator last, const Alloc& alloc); \end{itemdecl} \begin{itemdescr} @@ -14061,7 +15874,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R, class Alloc> - queue(from_range_t, R&& rg, const Alloc& a); + constexpr queue(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14076,7 +15889,7 @@ \indexlibrarymember{push_range}{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14092,7 +15905,7 @@ \indexlibrarymember{operator==}{queue}% \begin{itemdecl} template - bool operator==(const queue& x, const queue& y); + constexpr bool operator==(const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14104,7 +15917,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{queue}}% \begin{itemdecl} template - bool operator!=(const queue& x, const queue& y); + constexpr bool operator!=(const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14116,7 +15929,7 @@ \indexlibrarymember{operator<}{queue}% \begin{itemdecl} template - bool operator< (const queue& x, const queue& y); + constexpr bool operator< (const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14128,7 +15941,7 @@ \indexlibrarymember{operator>}{queue}% \begin{itemdecl} template - bool operator> (const queue& x, const queue& y); + constexpr bool operator> (const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14140,7 +15953,7 @@ \indexlibrarymember{operator<=}{queue}% \begin{itemdecl} template - bool operator<=(const queue& x, const queue& y); + constexpr bool operator<=(const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14152,8 +15965,7 @@ \indexlibrarymember{operator>=}{queue}% \begin{itemdecl} template - bool operator>=(const queue& x, - const queue& y); + constexpr bool operator>=(const queue& x, const queue& y); \end{itemdecl} \begin{itemdescr} @@ -14165,7 +15977,7 @@ \indexlibrarymember{operator<=>}{queue}% \begin{itemdecl} template - compare_three_way_result_t + constexpr compare_three_way_result_t operator<=>(const queue& x, const queue& y); \end{itemdecl} @@ -14180,7 +15992,8 @@ \indexlibrarymember{swap}{queue}% \begin{itemdecl} template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(queue& x, queue& y) + noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -14235,51 +16048,54 @@ Compare comp; public: - priority_queue() : priority_queue(Compare()) {} - explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} - priority_queue(const Compare& x, const Container&); - priority_queue(const Compare& x, Container&&); + constexpr priority_queue() : priority_queue(Compare()) {} + constexpr explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} + constexpr priority_queue(const Compare& x, const Container&); + constexpr priority_queue(const Compare& x, Container&&); template - priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& x = Compare()); template - priority_queue(InputIterator first, InputIterator last, const Compare& x, - const Container&); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container&); template - priority_queue(InputIterator first, InputIterator last, const Compare& x, - Container&&); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&&); template<@\exposconcept{container-compatible-range}@ R> - priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); - template explicit priority_queue(const Alloc&); - template priority_queue(const Compare&, const Alloc&); - template priority_queue(const Compare&, const Container&, const Alloc&); - template priority_queue(const Compare&, Container&&, const Alloc&); - template priority_queue(const priority_queue&, const Alloc&); - template priority_queue(priority_queue&&, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); + template constexpr explicit priority_queue(const Alloc&); + template constexpr priority_queue(const Compare&, const Alloc&); + template + constexpr priority_queue(const Compare&, const Container&, const Alloc&); + template constexpr priority_queue(const Compare&, Container&&, const Alloc&); + template constexpr priority_queue(const priority_queue&, const Alloc&); + template constexpr priority_queue(priority_queue&&, const Alloc&); template - priority_queue(InputIterator, InputIterator, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Alloc&); template - priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&); template - priority_queue(InputIterator, InputIterator, const Compare&, const Container&, - const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Container&, + const Alloc&); template - priority_queue(InputIterator, InputIterator, const Compare&, Container&&, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, Container&&, + const Alloc&); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - priority_queue(from_range_t, R&& rg, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Alloc&); - [[nodiscard]] bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - const_reference top() const { return c.front(); } - void push(const value_type& x); - void push(value_type&& x); + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr const_reference top() const { return c.front(); } + constexpr void push(const value_type& x); + constexpr void push(value_type&& x); template<@\exposconcept{container-compatible-range}@ R> - void push_range(R&& rg); - template void emplace(Args&&... args); - void pop(); - void swap(priority_queue& q) noexcept(is_nothrow_swappable_v && - is_nothrow_swappable_v) + constexpr void push_range(R&& rg); + template constexpr void emplace(Args&&... args); + constexpr void pop(); + constexpr void swap(priority_queue& q) + noexcept(is_nothrow_swappable_v && is_nothrow_swappable_v) { using std::swap; swap(c, q.c); swap(comp, q.comp); } }; @@ -14337,8 +16153,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -priority_queue(const Compare& x, const Container& y); -priority_queue(const Compare& x, Container&& y); +constexpr priority_queue(const Compare& x, const Container& y); +constexpr priority_queue(const Compare& x, Container&& y); \end{itemdecl} \begin{itemdescr} @@ -14360,7 +16176,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); \end{itemdecl} \begin{itemdescr} @@ -14380,9 +16196,11 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container& y); template - priority_queue(InputIterator first, InputIterator last, const Compare& x, Container&& y); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&& y); \end{itemdecl} \begin{itemdescr} @@ -14406,7 +16224,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); + constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); \end{itemdecl} \begin{itemdescr} @@ -14429,7 +16247,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template explicit priority_queue(const Alloc& a); +template constexpr explicit priority_queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14440,7 +16258,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template priority_queue(const Compare& compare, const Alloc& a); +template constexpr priority_queue(const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14452,7 +16270,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(const Compare& compare, const Container& cont, const Alloc& a); + constexpr priority_queue(const Compare& compare, const Container& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14466,7 +16284,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(const Compare& compare, Container&& cont, const Alloc& a); + constexpr priority_queue(const Compare& compare, Container&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14479,7 +16297,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template priority_queue(const priority_queue& q, const Alloc& a); +template constexpr priority_queue(const priority_queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14491,7 +16309,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template priority_queue(priority_queue&& q, const Alloc& a); +template constexpr priority_queue(priority_queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14504,7 +16322,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14521,7 +16339,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Compare& compare, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14538,8 +16357,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Compare& compare, - const Container& cont, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + const Container& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14555,8 +16374,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template - priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& cont, - const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + Container&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14573,7 +16392,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R, class Alloc> - priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a); + constexpr priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14587,22 +16406,23 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R, class Alloc> - priority_queue(from_range_t, R&& rg, const Alloc& a); + constexpr priority_queue(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} \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} \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(const value_type& x); +constexpr void push(const value_type& x); \end{itemdecl} \begin{itemdescr} @@ -14617,7 +16437,7 @@ \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(value_type&& x); +constexpr void push(value_type&& x); \end{itemdecl} \begin{itemdescr} @@ -14633,7 +16453,7 @@ \indexlibrarymember{push_range}{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14652,7 +16472,7 @@ \indexlibrarymember{emplace}{priority_queue}% \begin{itemdecl} -template void emplace(Args&&... args); +template constexpr void emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -14665,10 +16485,9 @@ \end{codeblock} \end{itemdescr} - \indexlibrarymember{pop}{priority_queue}% \begin{itemdecl} -void pop(); +constexpr void pop(); \end{itemdecl} \begin{itemdescr} @@ -14686,8 +16505,8 @@ \indexlibrarymember{swap}{priority_queue}% \begin{itemdecl} template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(priority_queue& x, + priority_queue& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -14701,6 +16520,45 @@ 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 + constexpr bool operator==(const stack& x, const stack& y); + template + constexpr bool operator!=(const stack& x, const stack& y); + template + constexpr bool operator< (const stack& x, const stack& y); + template + constexpr bool operator> (const stack& x, const stack& y); + template + constexpr bool operator<=(const stack& x, const stack& y); + template + constexpr bool operator>=(const stack& x, const stack& y); + template + constexpr compare_three_way_result_t + operator<=>(const stack& x, const stack& y); + + template + constexpr 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} @@ -14738,34 +16596,35 @@ Container c; public: - stack() : stack(Container()) {} - explicit stack(const Container&); - explicit stack(Container&&); - template stack(InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@ R> stack(from_range_t, R&& rg); - template explicit stack(const Alloc&); - template stack(const Container&, const Alloc&); - template stack(Container&&, const Alloc&); - template stack(const stack&, const Alloc&); - template stack(stack&&, const Alloc&); + constexpr stack() : stack(Container()) {} + constexpr explicit stack(const Container&); + constexpr explicit stack(Container&&); + template constexpr stack(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr stack(from_range_t, R&& rg); + template constexpr explicit stack(const Alloc&); + template constexpr stack(const Container&, const Alloc&); + template constexpr stack(Container&&, const Alloc&); + template constexpr stack(const stack&, const Alloc&); + template constexpr stack(stack&&, const Alloc&); template - stack(InputIterator first, InputIterator last, const Alloc&); + constexpr stack(InputIterator first, InputIterator last, const Alloc&); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - stack(from_range_t, R&& rg, const Alloc&); - - [[nodiscard]] bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference top() { return c.back(); } - const_reference top() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void push(value_type&& x) { c.push_back(std::move(x)); } + constexpr stack(from_range_t, R&& rg, const Alloc&); + + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr reference top() { return c.back(); } + constexpr const_reference top() const { return c.back(); } + constexpr void push(const value_type& x) { c.push_back(x); } + constexpr void push(value_type&& x) { c.push_back(std::move(x)); } template<@\exposconcept{container-compatible-range}@ R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); template - decltype(auto) emplace(Args&&... args) + constexpr decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward(args)...); } - void pop() { c.pop_back(); } - void swap(stack& s) noexcept(is_nothrow_swappable_v) + constexpr void pop() { c.pop_back(); } + constexpr void swap(stack& s) noexcept(is_nothrow_swappable_v) { using std::swap; swap(c, s.c); } }; @@ -14800,7 +16659,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(const Container& cont); +constexpr explicit stack(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -14811,7 +16670,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(Container&& cont); +constexpr explicit stack(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -14823,7 +16682,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template - stack(InputIterator first, InputIterator last); + constexpr stack(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -14836,7 +16695,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - stack(from_range_t, R&& rg); + constexpr stack(from_range_t, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14853,7 +16712,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template explicit stack(const Alloc& a); +template constexpr explicit stack(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14864,7 +16723,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template stack(const container_type& cont, const Alloc& a); +template constexpr stack(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14876,7 +16735,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template stack(container_type&& cont, const Alloc& a); +template constexpr stack(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14888,7 +16747,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template stack(const stack& s, const Alloc& a); +template constexpr stack(const stack& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14900,7 +16759,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template stack(stack&& s, const Alloc& a); +template constexpr stack(stack&& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14913,7 +16772,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template - stack(InputIterator first, InputIterator last, const Alloc& alloc); + constexpr stack(InputIterator first, InputIterator last, const Alloc& alloc); \end{itemdecl} \begin{itemdescr} @@ -14928,7 +16787,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R, class Alloc> - stack(from_range_t, R&& rg, const Alloc& a); + constexpr stack(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14943,7 +16802,7 @@ \indexlibrarymember{push_range}{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14959,7 +16818,7 @@ \indexlibrarymember{operator==}{stack}% \begin{itemdecl} template - bool operator==(const stack& x, const stack& y); + constexpr bool operator==(const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -14971,7 +16830,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{stack}}% \begin{itemdecl} template - bool operator!=(const stack& x, const stack& y); + constexpr bool operator!=(const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -14983,7 +16842,7 @@ \indexlibrarymember{operator<}{stack}% \begin{itemdecl} template - bool operator< (const stack& x, const stack& y); + constexpr bool operator< (const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -14995,7 +16854,7 @@ \indexlibrarymember{operator>}{stack}% \begin{itemdecl} template - bool operator> (const stack& x, const stack& y); + constexpr bool operator> (const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -15007,7 +16866,7 @@ \indexlibrarymember{operator<=}{stack}% \begin{itemdecl} template - bool operator<=(const stack& x, const stack& y); + constexpr bool operator<=(const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -15019,7 +16878,7 @@ \indexlibrarymember{operator>=}{stack}% \begin{itemdecl} template - bool operator>=(const stack& x, const stack& y); + constexpr bool operator>=(const stack& x, const stack& y); \end{itemdecl} \begin{itemdescr} @@ -15031,7 +16890,7 @@ \indexlibrarymember{operator<=>}{stack}% \begin{itemdecl} template - compare_three_way_result_t + constexpr compare_three_way_result_t operator<=>(const stack& x, const stack& y); \end{itemdecl} @@ -15046,7 +16905,8 @@ \indexlibrarymember{swap}{stack}% \begin{itemdecl} template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(stack& x, stack& y) + noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -15059,6 +16919,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 + constexpr 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 + constexpr 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} @@ -15167,6 +17075,10 @@ that contains equal elements, is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.map.defn]{Definition} \begin{codeblock} @@ -15193,12 +17105,12 @@ class value_compare { private: - key_compare comp; // \expos - value_compare(key_compare c) : comp(c) { } // \expos + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos public: - bool operator()(const_reference x, const_reference y) const { - return comp(x.first, y.first); + constexpr bool operator()(const_reference x, const_reference y) const { + return @\exposid{comp}@(x.first, y.first); } }; @@ -15207,233 +17119,242 @@ mapped_container_type values; }; - // \ref{flat.map.cons}, construct/copy/destroy - flat_map() : flat_map(key_compare()) { } - - template - flat_map(const flat_map&, const Allocator& a); - template - flat_map(flat_map&&, const Allocator& a); - - flat_map(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); - template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Allocator& a); - template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); - - flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); - template - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Allocator& a); - template - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); - - explicit flat_map(const key_compare& comp) - : c(), compare(comp) { } - template - flat_map(const key_compare& comp, const Allocator& a); - template - explicit flat_map(const Allocator& a); + // \ref{flat.map.cons}, constructors + constexpr flat_map() : flat_map(key_compare()) { } + + constexpr explicit flat_map(const key_compare& comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { } + + constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + constexpr flat_map(sorted_unique_t, key_container_type key_cont, + mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + template + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template - flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) - : c(), compare(comp) { insert(first, last); } - template - flat_map(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_map(InputIterator first, InputIterator last, const Allocator& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(sorted_unique, first, last); } template<@\exposconcept{container-compatible-range}@ R> - flat_map(from_range_t fr, R&& rg) - : flat_map(fr, std::forward(rg), key_compare()) { } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_map(from_range_t, R&& rg, const Allocator& a); + constexpr flat_map(from_range_t, R&& rg) + : flat_map(from_range, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R> - flat_map(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp) : flat_map(comp) { insert_range(std::forward(rg)); } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); - template - flat_map(sorted_unique_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : c(), compare(comp) { insert(s, first, last); } - template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); - - flat_map(initializer_list il, const key_compare& comp = key_compare()) + constexpr flat_map(initializer_list il, const key_compare& comp = key_compare()) : flat_map(il.begin(), il.end(), comp) { } - template - flat_map(initializer_list il, const key_compare& comp, const Allocator& a); - template - flat_map(initializer_list il, const Allocator& a); - - flat_map(sorted_unique_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_map(s, il.begin(), il.end(), comp) { } - template - flat_map(sorted_unique_t, initializer_list il, - const key_compare& comp, const Allocator& a); - template - flat_map(sorted_unique_t, initializer_list il, const Allocator& a); - flat_map& operator=(initializer_list il); + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp = key_compare()) + : flat_map(sorted_unique, il.begin(), il.end(), comp) { } + + // \ref{flat.map.cons.alloc}, constructors with allocators + + template + constexpr explicit flat_map(const Alloc& a); + template + constexpr flat_map(const key_compare& comp, const Alloc& a); + template + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const Alloc& a); + template + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); + template + constexpr flat_map(const flat_map&, const Alloc& a); + template + constexpr flat_map(flat_map&&, const Alloc& a); + template + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_map(initializer_list il, const Alloc& a); + template + constexpr flat_map(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_map& operator=(initializer_list); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // \ref{flat.map.capacity}, capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.map.access}, element access - mapped_type& operator[](const key_type& x); - mapped_type& operator[](key_type&& x); - template mapped_type& operator[](K&& x); - mapped_type& at(const key_type& x); - const mapped_type& at(const key_type& x) const; - template mapped_type& at(const K& x); - template const mapped_type& at(const K& x) const; + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template constexpr mapped_type& at(const K& x); + template constexpr const mapped_type& at(const K& x) const; // \ref{flat.map.modifiers}, modifiers - template pair emplace(Args&&... args); + template constexpr pair emplace(Args&&... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& x) + constexpr pair insert(const value_type& x) { return emplace(x); } - pair insert(value_type&& x) + constexpr pair insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template pair insert(P&& x); + template constexpr pair insert(P&& x); template - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list il) + constexpr void insert(initializer_list il) { insert(il.begin(), il.end()); } - void insert(sorted_unique_t s, initializer_list il) - { insert(s, il.begin(), il.end()); } + constexpr void insert(sorted_unique_t, initializer_list il) + { insert(sorted_unique, il.begin(), il.end()); } - containers extract() &&; - void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - - void swap(flat_map& y) noexcept; - void clear() noexcept; + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - // observers - key_compare key_comp() const; - value_compare value_comp() const; - - const key_container_type& keys() const noexcept { return c.keys; } - const mapped_container_type& values() const noexcept { return c.values; } - - // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; - - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr void swap(flat_map& y) noexcept; + constexpr void clear() noexcept; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; - template pair equal_range(const K& x); - template pair equal_range(const K& x) const; + // map operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; - friend bool operator==(const flat_map& x, const flat_map& y); + constexpr friend bool operator==(const flat_map& x, const flat_map& y); - friend @\exposid{synth-three-way-result}@ + constexpr friend @\exposid{synth-three-way-result}@ operator<=>(const flat_map& x, const flat_map& y); - friend void swap(flat_map& x, flat_map& y) noexcept + constexpr friend void swap(flat_map& x, flat_map& y) noexcept { x.swap(y); } private: - containers c; // \expos - key_compare compare; // \expos + containers @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos - struct key_equiv { // \expos - key_equiv(key_compare c) : comp(c) { } - bool operator()(const_reference x, const_reference y) const { + struct @\exposid{key-equiv}@ { // \expos + constexpr @\exposid{key-equiv}@(key_compare c) : comp(c) { } + constexpr bool operator()(const_reference x, const_reference y) const { return !comp(x.first, y.first) && !comp(y.first, x.first); } key_compare comp; @@ -15516,25 +17437,25 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -flat_map(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes -\tcode{c.keys} with \tcode{std::move(key_cont)}, -\tcode{c.values} with \tcode{std::move(mapped_cont)}, and -\tcode{compare} with \tcode{comp}; +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}; sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}; and finally erases the duplicate elements as if by: \begin{codeblock} -auto zv = views::zip(c.keys, c.values); -auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto zv = views::zip(@\exposid{c}@.keys, @\exposid{c}@.values); +auto it = ranges::unique(zv, @\exposid{key-equiv}@(@\exposid{compare}@)).begin(); auto dist = distance(zv.begin(), it); -c.keys.erase(c.keys.begin() + dist, c.keys.end()); -c.values.erase(c.values.begin() + dist, c.values.end()); +@\exposid{c}@.keys.erase(@\exposid{c}@.keys.begin() + dist, @\exposid{c}@.keys.end()); +@\exposid{c}@.values.erase(@\exposid{c}@.values.begin() + dist, @\exposid{c}@.values.end()); \end{codeblock} \pnum @@ -15546,74 +17467,71 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Allocator& a); -template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); +constexpr flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects -Equivalent to \tcode{flat_map(key_cont, mapped_cont)} and -\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively, -except that \tcode{c.keys} and \tcode{c.values} are constructed with -uses-allocator construction\iref{allocator.uses.construction}. +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}. \pnum \complexity -Same as \tcode{flat_map(key_cont, mapped_cont)} and -\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively. +Constant. \end{itemdescr} +\rSec3[flat.map.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true} +and \tcode{uses_allocator_v} is \tcode{true}. + \indexlibraryctor{flat_map}% \begin{itemdecl} -flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +template + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Alloc& a); +template + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes -\tcode{c.keys} with \tcode{std::move(key_cont)}, -\tcode{c.values} with \tcode{std::move(mapped_cont)}, and -\tcode{compare} with \tcode{comp}. +Equivalent to \tcode{flat_map(key_cont, mapped_cont)} and +\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed with +uses-allocator construction\iref{allocator.uses.construction}. \pnum \complexity -Constant. +Same as \tcode{flat_map(key_cont, mapped_cont)} and +\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively. \end{itemdescr} \indexlibraryctor{flat_map}% \begin{itemdecl} -template - flat_map(sorted_unique_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Allocator& a); -template - flat_map(sorted_unique_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const key_compare& comp, - const Allocator& a); +template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects -Equivalent to \tcode{flat_map(s, key_cont, mapped_cont)} and -\tcode{flat_map(s, key_cont, \linebreak{}mapped_cont, comp)}, respectively, -except that \tcode{c.keys} and \tcode{c.values} are constructed +Equivalent to \tcode{flat_map(sorted_unique, key_cont, mapped_cont)} and +\tcode{flat_map(sorted_unique, key_cont, \linebreak{}mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \pnum @@ -15623,48 +17541,44 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -template - flat_map(const flat_map&, const Allocator& a); -template - flat_map(flat_map&&, const Allocator& a); -template - flat_map(const key_compare& comp, const Allocator& a); -template - explicit flat_map(const Allocator& a); -template - flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); -template - flat_map(InputIterator first, InputIterator last, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_map(from_range_t, R&& rg, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); -template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); -template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); -template - flat_map(initializer_list il, const key_compare& comp, const Allocator& a); -template - flat_map(initializer_list il, const Allocator& a); -template - flat_map(sorted_unique_t, initializer_list il, - const key_compare& comp, const Allocator& a); -template - flat_map(sorted_unique_t, initializer_list il, const Allocator& a); +template + constexpr explicit flat_map(const Alloc& a); +template + constexpr flat_map(const key_compare& comp, const Alloc& a); +template + constexpr flat_map(const flat_map&, const Alloc& a); +template + constexpr flat_map(flat_map&&, const Alloc& a); +template + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_map(initializer_list il, const Alloc& a); +template + constexpr flat_map(initializer_list il, const key_compare& comp, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to the corresponding non-allocator constructors -except that \tcode{c.keys} and \tcode{c.values} are constructed +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \end{itemdescr} @@ -15672,31 +17586,31 @@ \indexlibrarymember{size}{flat_map}% \begin{itemdecl} -size_type size() const noexcept; +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{c.keys.size()}. +\tcode{\exposid{c}.keys.size()}. \end{itemdescr} \indexlibrarymember{max_size}{flat_map}% \begin{itemdecl} -size_type max_size() const noexcept; +constexpr size_type max_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{min(c.keys.max_size(), c.values.max_size())}. +\tcode{min(\exposid{c}.keys.max_size(), \exposid{c}.values.max_size())}. \end{itemdescr} \rSec3[flat.map.access]{Access} \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -mapped_type& operator[](const key_type& x); +constexpr mapped_type& operator[](const key_type& x); \end{itemdecl} \begin{itemdescr} @@ -15707,7 +17621,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -mapped_type& operator[](key_type&& x); +constexpr mapped_type& operator[](key_type&& x); \end{itemdecl} \begin{itemdescr} @@ -15718,7 +17632,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -template mapped_type& operator[](K&& x); +template constexpr mapped_type& operator[](K&& x); \end{itemdecl} \begin{itemdescr} @@ -15734,8 +17648,8 @@ \indexlibrarymember{at}{flat_map}% \begin{itemdecl} -mapped_type& at(const key_type& x); -const mapped_type& at(const key_type& x) const; +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; \end{itemdecl} \begin{itemdescr} @@ -15756,8 +17670,8 @@ \indexlibrarymember{at}{flat_map}% \begin{itemdecl} -template mapped_type& at(const K& x); -template const mapped_type& at(const K& x) const; +template constexpr mapped_type& at(const K& x); +template constexpr const mapped_type& at(const K& x) const; \end{itemdecl} \begin{itemdescr} @@ -15789,7 +17703,7 @@ \indexlibrarymember{emplace}{flat_map}% \begin{itemdecl} -template pair emplace(Args&&... args); +template constexpr pair emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -15806,10 +17720,10 @@ \tcode{*this} is unchanged. Otherwise, equivalent to: \begin{codeblock} -auto key_it = ranges::upper_bound(c.keys, t.first, compare); -auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); -c.keys.insert(key_it, std::move(t.first)); -c.values.insert(value_it, std::move(t.second)); +auto key_it = ranges::upper_bound(@\exposid{c}@.keys, t.first, @\exposid{compare}@); +auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it); +@\exposid{c}@.keys.insert(key_it, std::move(t.first)); +@\exposid{c}@.values.insert(value_it, std::move(t.second)); \end{codeblock} \pnum @@ -15822,8 +17736,8 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} -template pair insert(P&& x); -template iterator insert(const_iterator position, P&& x); +template constexpr pair insert(P&& x); +template constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -15841,18 +17755,18 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Adds elements to \tcode{c} as if by: +Adds elements to \exposid{c} as if by: \begin{codeblock} for (; first != last; ++first) { value_type value = *first; - c.keys.insert(c.keys.end(), std::move(value.first)); - c.values.insert(c.values.end(), std::move(value.second)); + @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), std::move(value.first)); + @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), std::move(value.second)); } \end{codeblock} Then, sorts the range of newly inserted elements @@ -15861,11 +17775,11 @@ the sorted range of pre-existing elements into a single sorted range; and finally erases the duplicate elements as if by: \begin{codeblock} -auto zv = views::zip(c.keys, c.values); -auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto zv = views::zip(@\exposid{c}@.keys, @\exposid{c}@.values); +auto it = ranges::unique(zv, @\exposid{key-equiv}@(@\exposid{compare}@)).begin(); auto dist = distance(zv.begin(), it); -c.keys.erase(c.keys.begin() + dist, c.keys.end()); -c.values.erase(c.values.begin() + dist, c.values.end()); +@\exposid{c}@.keys.erase(@\exposid{c}@.keys.begin() + dist, @\exposid{c}@.keys.end()); +@\exposid{c}@.values.erase(@\exposid{c}@.values.begin() + dist, @\exposid{c}@.values.end()); \end{codeblock} \pnum @@ -15882,29 +17796,29 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} template - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Adds elements to \tcode{c} as if by: +Adds elements to \exposid{c} as if by: \begin{codeblock} for (; first != last; ++first) { value_type value = *first; - c.keys.insert(c.keys.end(), std::move(value.first)); - c.values.insert(c.values.end(), std::move(value.second)); + @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), std::move(value.first)); + @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), std::move(value.second)); } \end{codeblock} Then, merges the sorted range of newly added elements and the sorted range of pre-existing elements into a single sorted range; and finally erases the duplicate elements as if by: \begin{codeblock} -auto zv = views::zip(c.keys, c.values); -auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto zv = views::zip(@\exposid{c}@.keys, @\exposid{c}@.values); +auto it = ranges::unique(zv, @\exposid{key-equiv}@(@\exposid{compare}@)).begin(); auto dist = distance(zv.begin(), it); -c.keys.erase(c.keys.begin() + dist, c.keys.end()); -c.values.erase(c.values.begin() + dist, c.values.end()); +@\exposid{c}@.keys.erase(@\exposid{c}@.keys.begin() + dist, @\exposid{c}@.keys.end()); +@\exposid{c}@.values.erase(@\exposid{c}@.values.begin() + dist, @\exposid{c}@.values.end()); \end{codeblock} \pnum @@ -15919,17 +17833,17 @@ \indexlibrarymember{insert_range}{flat_map}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects -Adds elements to \tcode{c} as if by: +Adds elements to \exposid{c} as if by: \begin{codeblock} for (const auto& e : rg) { - c.keys.insert(c.keys.end(), e.first); - c.values.insert(c.values.end(), e.second); + @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), e.first); + @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), e.second); } \end{codeblock} Then, sorts the range of newly inserted elements @@ -15938,11 +17852,11 @@ the sorted range of pre-existing elements into a single sorted range; and finally erases the duplicate elements as if by: \begin{codeblock} -auto zv = views::zip(c.keys, c.values); -auto it = ranges::unique(zv, key_equiv(compare)).begin(); +auto zv = views::zip(@\exposid{c}@.keys, @\exposid{c}@.values); +auto it = ranges::unique(zv, @\exposid{key-equiv}@(@\exposid{compare}@)).begin(); auto dist = distance(zv.begin(), it); -c.keys.erase(c.keys.begin() + dist, c.keys.end()); -c.values.erase(c.values.begin() + dist, c.values.end()); +@\exposid{c}@.keys.erase(@\exposid{c}@.keys.begin() + dist, @\exposid{c}@.keys.end()); +@\exposid{c}@.values.erase(@\exposid{c}@.values.begin() + dist, @\exposid{c}@.values.end()); \end{codeblock} \pnum @@ -15959,13 +17873,13 @@ \indexlibrarymember{try_emplace}{flat_map}% \begin{itemdecl} template - pair try_emplace(const key_type& k, Args&&... args); + constexpr pair try_emplace(const key_type& k, Args&&... args); template - pair try_emplace(key_type&& k, Args&&... args); + constexpr pair try_emplace(key_type&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -15979,10 +17893,10 @@ \tcode{*this} and \tcode{args...} are unchanged. Otherwise equivalent to: \begin{codeblock} -auto key_it = ranges::upper_bound(c.keys, k, compare); -auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); -c.keys.insert(key_it, std::forward(k)); -c.values.emplace(value_it, std::forward(args)...); +auto key_it = ranges::upper_bound(@\exposid{c}@.keys, k, @\exposid{compare}@); +auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it); +@\exposid{c}@.keys.insert(key_it, std::forward(k)); +@\exposid{c}@.values.emplace(value_it, std::forward(args)...); \end{codeblock} \pnum @@ -16002,9 +17916,9 @@ \indexlibrarymember{try_emplace}{flat_map}% \begin{itemdecl} template - pair try_emplace(K&& k, Args&&... args); + constexpr pair try_emplace(K&& k, Args&&... args); template - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -16036,10 +17950,10 @@ \tcode{*this} and \tcode{args...} are unchanged. Otherwise equivalent to: \begin{codeblock} -auto key_it = ranges::upper_bound(c.keys, k, compare); -auto value_it = c.values.begin() + distance(c.keys.begin(), key_it); -c.keys.emplace(key_it, std::forward(k)); -c.values.emplace(value_it, std::forward(args)...); +auto key_it = ranges::upper_bound(@\exposid{c}@.keys, k, @\exposid{compare}@); +auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it); +@\exposid{c}@.keys.emplace(key_it, std::forward(k)); +@\exposid{c}@.values.emplace(value_it, std::forward(args)...); \end{codeblock} \pnum @@ -16058,13 +17972,13 @@ \indexlibrarymember{insert_or_assign}{flat_map}% \begin{itemdecl} template - pair insert_or_assign(const key_type& k, M&& obj); + constexpr pair insert_or_assign(const key_type& k, M&& obj); template - pair insert_or_assign(key_type&& k, M&& obj); + constexpr pair insert_or_assign(key_type&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -16103,9 +18017,9 @@ \indexlibrarymember{insert_or_assign}{flat_map}% \begin{itemdecl} template - pair insert_or_assign(K&& k, M&& obj); + constexpr pair insert_or_assign(K&& k, M&& obj); template - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -16158,7 +18072,7 @@ \indexlibrarymember{swap}{flat_map}% \begin{itemdecl} -void swap(flat_map& y) noexcept; +constexpr void swap(flat_map& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16166,15 +18080,15 @@ \effects Equivalent to: \begin{codeblock} -ranges::swap(compare, y.compare); -ranges::swap(c.keys, y.c.keys); -ranges::swap(c.values, y.c.values); +ranges::swap(@\exposid{compare}@, y.@\exposid{compare}@); +ranges::swap(@\exposid{c}@.keys, y.@\exposid{c}@.keys); +ranges::swap(@\exposid{c}@.values, y.@\exposid{c}@.values); \end{codeblock} \end{itemdescr} \indexlibrarymember{extract}{flat_map}% \begin{itemdecl} -containers extract() &&; +constexpr containers extract() &&; \end{itemdecl} \begin{itemdescr} @@ -16184,27 +18098,27 @@ \pnum \returns -\tcode{std::move(c)}. +\tcode{std::move(\exposid{c})}. \end{itemdescr} \indexlibrarymember{replace}{flat_map}% \begin{itemdecl} -void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); +constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{key_cont.size() == mapped_cont.size()} is \tcode{true}, -the elements of \tcode{key_cont} are sorted with respect to \tcode{compare}, and +the elements of \tcode{key_cont} are sorted with respect to \exposid{compare}, and \tcode{key_cont} contains no equal elements. \pnum \effects Equivalent to: \begin{codeblock} -c.keys = std::move(key_cont); -c.values = std::move(mapped_cont); +@\exposid{c}@.keys = std::move(key_cont); +@\exposid{c}@.values = std::move(mapped_cont); \end{codeblock} \end{itemdescr} @@ -16214,7 +18128,7 @@ \begin{itemdecl} template - typename flat_map::size_type + constexpr typename flat_map::size_type erase_if(flat_map& c, Predicate pred); \end{itemdecl} @@ -16356,6 +18270,10 @@ with a container, containers, or range that are not sorted with respect to \tcode{key_comp()} is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.multimap.defn]{Definition} \begin{codeblock} @@ -16382,12 +18300,12 @@ class value_compare { private: - key_compare comp; // \expos - value_compare(key_compare c) : comp(c) { } // \expos + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos public: - bool operator()(const_reference x, const_reference y) const { - return comp(x.first, y.first); + constexpr bool operator()(const_reference x, const_reference y) const { + return @\exposid{comp}@(x.first, y.first); } }; @@ -16396,202 +18314,207 @@ mapped_container_type values; }; - // \ref{flat.multimap.cons}, construct/copy/destroy - flat_multimap() : flat_multimap(key_compare()) { } + // \ref{flat.multimap.cons}, constructors + constexpr flat_multimap() : flat_multimap(key_compare()) { } - template - flat_multimap(const flat_multimap&, const Allocator& a); - template - flat_multimap(flat_multimap&&, const Allocator& a); + constexpr explicit flat_multimap(const key_compare& comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { } - flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); - template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Allocator& a); - template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); - - flat_multimap(sorted_equivalent_t, - key_container_type key_cont, mapped_container_type mapped_cont, + constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + constexpr flat_multimap(sorted_equivalent_t, + key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); - template - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Allocator& a); - template - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); - - explicit flat_multimap(const key_compare& comp) - : c(), compare(comp) { } - template - flat_multimap(const key_compare& comp, const Allocator& a); - template - explicit flat_multimap(const Allocator& a); template - flat_multimap(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : c(), compare(comp) + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } - template - flat_multimap(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_multimap(InputIterator first, InputIterator last, const Allocator& a); + + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(sorted_equivalent, first, last); } template<@\exposconcept{container-compatible-range}@ R> - flat_multimap(from_range_t fr, R&& rg) - : flat_multimap(fr, std::forward(rg), key_compare()) { } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multimap(from_range_t, R&& rg, const Allocator& a); + constexpr flat_multimap(from_range_t, R&& rg) + : flat_multimap(from_range, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R> - flat_multimap(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp) : flat_multimap(comp) { insert_range(std::forward(rg)); } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); - template - flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : c(), compare(comp) { insert(s, first, last); } - template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Allocator& a); - - flat_multimap(initializer_list il, const key_compare& comp = key_compare()) + constexpr flat_multimap(initializer_list il, + const key_compare& comp = key_compare()) : flat_multimap(il.begin(), il.end(), comp) { } - template - flat_multimap(initializer_list il, const key_compare& comp, - const Allocator& a); - template - flat_multimap(initializer_list il, const Allocator& a); - - flat_multimap(sorted_equivalent_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_multimap(s, il.begin(), il.end(), comp) { } - template - flat_multimap(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Allocator& a); - template - flat_multimap(sorted_equivalent_t, initializer_list il, const Allocator& a); - - flat_multimap& operator=(initializer_list il); + + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp = key_compare()) + : flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { } + + // \ref{flat.multimap.cons.alloc}, constructors with allocators + + template + constexpr explicit flat_multimap(const Alloc& a); + template + constexpr flat_multimap(const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(const flat_multimap&, const Alloc& a); + template + constexpr flat_multimap(flat_multimap&&, const Alloc& a); + template + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(initializer_list il, const Alloc& a); + template + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + flat_multimap& operator=(initializer_list); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template iterator emplace(Args&&... args); + template constexpr iterator emplace(Args&&... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x) + constexpr iterator insert(const value_type& x) { return emplace(x); } - iterator insert(value_type&& x) + constexpr iterator insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template iterator insert(P&& x); + template constexpr iterator insert(P&& x); template - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list il) + constexpr void insert(initializer_list il) { insert(il.begin(), il.end()); } - void insert(sorted_equivalent_t s, initializer_list il) - { insert(s, il.begin(), il.end()); } + constexpr void insert(sorted_equivalent_t, initializer_list il) + { insert(sorted_equivalent, il.begin(), il.end()); } - containers extract() &&; - void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); - void swap(flat_multimap&) noexcept; - void clear() noexcept; + constexpr void swap(flat_multimap&) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; - const key_container_type& keys() const noexcept { return c.keys; } - const mapped_container_type& values() const noexcept { return c.values; } + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; - friend bool operator==(const flat_multimap& x, const flat_multimap& y); + constexpr friend bool operator==(const flat_multimap& x, const flat_multimap& y); - friend @\exposid{synth-three-way-result}@ + constexpr friend @\exposid{synth-three-way-result}@ operator<=>(const flat_multimap& x, const flat_multimap& y); - friend void swap(flat_multimap& x, flat_multimap& y) noexcept + constexpr friend void swap(flat_multimap& x, flat_multimap& y) noexcept { x.swap(y); } private: - containers c; // \expos - key_compare compare; // \expos + containers @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos }; template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Allocator& a); -template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Allocator& a); +constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont, + mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects -Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)} and -\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively, -except that \tcode{c.keys} and \tcode{c.values} are constructed -with uses-allocator construction\iref{allocator.uses.construction}. +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}. \pnum \complexity -Same as \tcode{flat_multimap(key_cont, mapped_cont)} and -\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively. +Constant. \end{itemdescr} +\rSec3[flat.multimap.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true} +and \tcode{uses_allocator_v} is \tcode{true}. + \indexlibraryctor{flat_multimap}% \begin{itemdecl} -flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes -\tcode{c.keys} with \tcode{std::move(key_cont)}, -\tcode{c.values} with \tcode{std::move(mapped_cont)}, and -\tcode{compare} with \tcode{comp}. +Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)} and +\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. \pnum \complexity -Constant. +Same as \tcode{flat_multimap(key_cont, mapped_cont)} and +\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively. \end{itemdescr} \indexlibraryctor{flat_multimap}% \begin{itemdecl} -template - flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Allocator& a); -template - flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, +template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, - const Allocator& a); + const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects -Equivalent to \tcode{flat_multimap(s, key_cont, mapped_cont)} and -\tcode{flat_multimap(s, key_cont, mapped_cont, comp)}, respectively, -except that \tcode{c.keys} and \tcode{c.val\-ues} are constructed +Equivalent to \tcode{flat_multimap(sorted_equivalent, key_cont, mapped_cont)} and +\tcode{flat_multimap(sorted_equivalent, key_cont, mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.val\-ues} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \pnum @@ -16774,50 +18696,46 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} -template - flat_multimap(const flat_multimap&, const Allocator& a); -template - flat_multimap(flat_multimap&&, const Allocator& a); -template - flat_multimap(const key_compare& comp, const Allocator& a); -template - explicit flat_multimap(const Allocator& a); -template - flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, - const Allocator& a); -template - flat_multimap(InputIterator first, InputIterator last, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multimap(from_range_t, R&& rg, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); -template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); -template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Allocator& a); -template - flat_multimap(initializer_list il, const key_compare& comp, const Allocator& a); -template - flat_multimap(initializer_list il, const Allocator& a); -template - flat_multimap(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Allocator& a); -template - flat_multimap(sorted_equivalent_t, initializer_list il, const Allocator& a); +template + constexpr explicit flat_multimap(const Alloc& a); +template + constexpr flat_multimap(const key_compare& comp, const Alloc& a); +template + constexpr flat_multimap(const flat_multimap&, const Alloc& a); +template + constexpr flat_multimap(flat_multimap&&, const Alloc& a); +template + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_multimap(initializer_list il, const Alloc& a); +template + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true} and -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to the corresponding non-allocator constructors -except that \tcode{c.keys} and \tcode{c.values} are constructed +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed with uses-allocator construction\iref{allocator.uses.construction}. \end{itemdescr} @@ -16827,7 +18745,7 @@ \begin{itemdecl} template - typename flat_multimap::size_type + constexpr typename flat_multimap::size_type erase_if(flat_multimap& c, Predicate pred); \end{itemdecl} @@ -16860,6 +18778,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 + constexpr 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 + constexpr 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} @@ -16944,6 +18902,10 @@ with a range that is not sorted with respect to \tcode{key_comp()}, or that contains equal elements, is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.set.defn]{Definition} \begin{codeblock} @@ -16967,184 +18929,190 @@ using container_type = KeyContainer; // \ref{flat.set.cons}, constructors - flat_set() : flat_set(key_compare()) { } + constexpr flat_set() : flat_set(key_compare()) { } - template - flat_set(const flat_set&, const Allocator& a); - template - flat_set(flat_set&&, const Allocator& a); + constexpr explicit flat_set(const key_compare& comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { } - explicit flat_set(container_type cont, const key_compare& comp = key_compare()); - template - flat_set(const container_type& cont, const Allocator& a); - template - flat_set(const container_type& cont, const key_compare& comp, const Allocator& a); + constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare()); - flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare()) + constexpr flat_set(sorted_unique_t, container_type cont, + const key_compare& comp = key_compare()) : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } - template - flat_set(sorted_unique_t, const container_type& cont, const Allocator& a); - template - flat_set(sorted_unique_t, const container_type& cont, - const key_compare& comp, const Allocator& a); - - explicit flat_set(const key_compare& comp) - : @\exposid{c}@(), @\exposid{compare}@(comp) { } - template - flat_set(const key_compare& comp, const Allocator& a); - template - explicit flat_set(const Allocator& a); template - flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } - template - flat_set(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_set(InputIterator first, InputIterator last, const Allocator& a); + + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template<@\exposconcept{container-compatible-range}@ R> - flat_set(from_range_t fr, R&& rg) - : flat_set(fr, std::forward(rg), key_compare()) { } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_set(from_range_t, R&& rg, const Allocator& a); + constexpr flat_set(from_range_t, R&& rg) + : flat_set(from_range, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R> - flat_set(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp) : flat_set(comp) { insert_range(std::forward(rg)); } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); - - template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } - template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); - flat_set(initializer_list il, const key_compare& comp = key_compare()) + constexpr flat_set(initializer_list il, const key_compare& comp = key_compare()) : flat_set(il.begin(), il.end(), comp) { } - template - flat_set(initializer_list il, const key_compare& comp, const Allocator& a); - template - flat_set(initializer_list il, const Allocator& a); - flat_set(sorted_unique_t s, initializer_list il, + constexpr flat_set(sorted_unique_t, initializer_list il, const key_compare& comp = key_compare()) - : flat_set(s, il.begin(), il.end(), comp) { } - template - flat_set(sorted_unique_t, initializer_list il, - const key_compare& comp, const Allocator& a); - template - flat_set(sorted_unique_t, initializer_list il, const Allocator& a); - - flat_set& operator=(initializer_list); + : flat_set(sorted_unique, il.begin(), il.end(), comp) { } + + // \ref{flat.set.cons.alloc}, constructors with allocators + + template + constexpr explicit flat_set(const Alloc& a); + template + constexpr flat_set(const key_compare& comp, const Alloc& a); + template + constexpr flat_set(const container_type& cont, const Alloc& a); + template + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_set(const flat_set&, const Alloc& a); + template + constexpr flat_set(flat_set&&, const Alloc& a); + template + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_set(initializer_list il, const Alloc& a); + template + constexpr flat_set(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_set& operator=(initializer_list); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.set.modifiers}, modifiers - template pair emplace(Args&&... args); + template constexpr pair emplace(Args&&... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& x) + constexpr pair insert(const value_type& x) { return emplace(x); } - pair insert(value_type&& x) + constexpr pair insert(value_type&& x) { return emplace(std::move(x)); } - template pair insert(K&& x); - iterator insert(const_iterator position, const value_type& x) + template constexpr pair insert(K&& x); + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template iterator insert(const_iterator hint, K&& x); + template constexpr iterator insert(const_iterator hint, K&& x); template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list il) + constexpr void insert(initializer_list il) { insert(il.begin(), il.end()); } - void insert(sorted_unique_t s, initializer_list il) - { insert(s, il.begin(), il.end()); } + constexpr void insert(sorted_unique_t, initializer_list il) + { insert(sorted_unique, il.begin(), il.end()); } - container_type extract() &&; - void replace(container_type&&); + constexpr container_type extract() &&; + constexpr void replace(container_type&&); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); - void swap(flat_set& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_set& y) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; - friend bool operator==(const flat_set& x, const flat_set& y); + constexpr friend bool operator==(const flat_set& x, const flat_set& y); - friend @\placeholder{synth-three-way-result}@ + constexpr friend @\placeholder{synth-three-way-result}@ operator<=>(const flat_set& x, const flat_set& y); - friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } + constexpr friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } private: container_type @\exposidnc{c}@; // \expos @@ -17212,7 +19180,7 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -explicit flat_set(container_type cont, const key_compare& comp = key_compare()); +constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -17226,23 +19194,25 @@ \pnum \complexity -Linear in $N$ if \tcode{cont} is sorted with respect to \exposid{compare} and +Linear in $N$ if \tcode{cont} is already sorted with respect to \exposid{compare} and otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. \end{itemdescr} +\rSec3[flat.set.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true}. + \indexlibraryctor{flat_set}% \begin{itemdecl} -template - flat_set(const container_type& cont, const Allocator& a); -template - flat_set(const container_type& cont, const key_compare& comp, const Allocator& a); +template + constexpr flat_set(const container_type& cont, const Alloc& a); +template + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to @@ -17257,22 +19227,18 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -template - flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a); -template - flat_set(sorted_unique_t s, const container_type& cont, - const key_compare& comp, const Allocator& a); +template + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to -\tcode{flat_set(s, cont)} and \tcode{flat_set(s, cont, comp)}, respectively, +\tcode{flat_set(sorted_unique, cont)} and \tcode{flat_set(sorted_unique, cont, comp)}, respectively, except that \exposid{c} is constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -17283,43 +19249,40 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -template - flat_set(const flat_set&, const Allocator& a); -template - flat_set(flat_set&&, const Allocator& a); -template - flat_set(const key_compare& comp, const Allocator& a); -template - explicit flat_set(const Allocator& a); -template - flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a); -template - flat_set(InputIterator first, InputIterator last, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_set(from_range_t, R&& rg, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); -template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); -template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a); -template - flat_set(initializer_list il, const key_compare& comp, const Allocator& a); -template - flat_set(initializer_list il, const Allocator& a); -template - flat_set(sorted_unique_t, initializer_list il, - const key_compare& comp, const Allocator& a); -template - flat_set(sorted_unique_t, initializer_list il, const Allocator& a); +template + constexpr explicit flat_set(const Alloc& a); +template + constexpr flat_set(const key_compare& comp, const Alloc& a); +template + constexpr flat_set(const flat_set&, const Alloc& a); +template + constexpr flat_set(flat_set&&, const Alloc& a); +template + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_set(initializer_list il, const Alloc& a); +template + constexpr flat_set(initializer_list il, const key_compare& comp, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to the corresponding non-allocator constructors @@ -17331,8 +19294,8 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} -template pair insert(K&& x); -template iterator insert(const_iterator hint, K&& x); +template constexpr pair insert(K&& x); +template constexpr iterator insert(const_iterator hint, K&& x); \end{itemdecl} \begin{itemdescr} @@ -17345,7 +19308,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 @@ -17363,10 +19326,10 @@ 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); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -17396,7 +19359,7 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} template - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -17412,7 +19375,7 @@ \indexlibrarymember{insert_range}{flat_set}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -17443,7 +19406,7 @@ \indexlibrarymember{swap}{flat_set}% \begin{itemdecl} -void swap(flat_set& y) noexcept; +constexpr void swap(flat_set& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -17456,9 +19419,9 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{extract}{flatset}% +\indexlibrarymember{extract}{flat_set}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -17473,7 +19436,7 @@ \indexlibrarymember{replace}{flat_set}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -17492,7 +19455,7 @@ \indexlibrarymember{erase_if}{flat_set}% \begin{itemdecl} template - typename flat_set::size_type + constexpr typename flat_set::size_type erase_if(flat_set& c, Predicate pred); \end{itemdecl} @@ -17607,6 +19570,10 @@ that takes a \tcode{sorted_equivalent_t} argument with a range that is not sorted with respect to \tcode{key_comp()} is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.multiset.defn]{Definition} \begin{codeblock} @@ -17630,186 +19597,192 @@ using container_type = KeyContainer; // \ref{flat.multiset.cons}, constructors - flat_multiset() : flat_multiset(key_compare()) { } + constexpr flat_multiset() : flat_multiset(key_compare()) { } - template - flat_multiset(const flat_multiset&, const Allocator& a); - template - flat_multiset(flat_multiset&&, const Allocator& a); + constexpr explicit flat_multiset(const key_compare& comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { } - explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); - template - flat_multiset(const container_type& cont, const Allocator& a); - template - flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a); + constexpr explicit flat_multiset(container_type cont, + const key_compare& comp = key_compare()); - flat_multiset(sorted_equivalent_t, container_type cont, - const key_compare& comp = key_compare()) + constexpr flat_multiset(sorted_equivalent_t, container_type cont, + const key_compare& comp = key_compare()) : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } - template - flat_multiset(sorted_equivalent_t, const container_type& cont, const Allocator& a); - template - flat_multiset(sorted_equivalent_t, const container_type& cont, - const key_compare& comp, const Allocator& a); - - explicit flat_multiset(const key_compare& comp) - : @\exposid{c}@(), @\exposid{compare}@(comp) { } - template - flat_multiset(const key_compare& comp, const Allocator& a); - template - explicit flat_multiset(const Allocator& a); template - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } - template - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_multiset(InputIterator first, InputIterator last, const Allocator& a); + + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template<@\exposconcept{container-compatible-range}@ R> - flat_multiset(from_range_t fr, R&& rg) - : flat_multiset(fr, std::forward(rg), key_compare()) { } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const Allocator& a); + constexpr flat_multiset(from_range_t, R&& rg) + : flat_multiset(from_range, std::forward(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@ R> - flat_multiset(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp) : flat_multiset(comp) { insert_range(std::forward(rg)); } - template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); - template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } - template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); - template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const Allocator& a); - - flat_multiset(initializer_list il, const key_compare& comp = key_compare()) + constexpr flat_multiset(initializer_list il, + const key_compare& comp = key_compare()) : flat_multiset(il.begin(), il.end(), comp) { } - template - flat_multiset(initializer_list il, const key_compare& comp, - const Allocator& a); - template - flat_multiset(initializer_list il, const Allocator& a); - - flat_multiset(sorted_equivalent_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_multiset(s, il.begin(), il.end(), comp) { } - template - flat_multiset(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Allocator& a); - template - flat_multiset(sorted_equivalent_t, initializer_list il, const Allocator& a); - - flat_multiset& operator=(initializer_list); + + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp = key_compare()) + : flat_multiset(sorted_equivalent, il.begin(), il.end(), comp) { } + + // \ref{flat.multiset.cons.alloc}, constructors with allocators + + template + constexpr explicit flat_multiset(const Alloc& a); + template + constexpr flat_multiset(const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(const container_type& cont, const Alloc& a); + template + constexpr flat_multiset(const container_type& cont, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(const flat_multiset&, const Alloc& a); + template + constexpr flat_multiset(flat_multiset&&, const Alloc& a); + template + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(initializer_list il, const Alloc& a); + template + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_multiset& operator=(initializer_list); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; // capacity - [[nodiscard]] bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.multiset.modifiers}, modifiers - template iterator emplace(Args&&... args); + template constexpr iterator emplace(Args&&... args); template - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x) + constexpr iterator insert(const value_type& x) { return emplace(x); } - iterator insert(value_type&& x) + constexpr iterator insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@ R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list il) + constexpr void insert(initializer_list il) { insert(il.begin(), il.end()); } - void insert(sorted_equivalent_t s, initializer_list il) - { insert(s, il.begin(), il.end()); } + constexpr void insert(sorted_equivalent_t, initializer_list il) + { insert(sorted_equivalent, il.begin(), il.end()); } - container_type extract() &&; - void replace(container_type&&); + constexpr container_type extract() &&; + constexpr void replace(container_type&&); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); - void swap(flat_multiset& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_multiset& y) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template iterator find(const K& x); - template const_iterator find(const K& x) const; + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; - size_type count(const key_type& x) const; - template size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template iterator lower_bound(const K& x); - template const_iterator lower_bound(const K& x) const; + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template iterator upper_bound(const K& x); - template const_iterator upper_bound(const K& x) const; + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; template - pair equal_range(const K& x); + constexpr pair equal_range(const K& x); template - pair equal_range(const K& x) const; + constexpr pair equal_range(const K& x) const; - friend bool operator==(const flat_multiset& x, const flat_multiset& y); + constexpr friend bool operator==(const flat_multiset& x, const flat_multiset& y); friend @\placeholder{synth-three-way-result}@ - operator<=>(const flat_multiset& x, const flat_multiset& y); + constexpr operator<=>(const flat_multiset& x, const flat_multiset& y); - friend void swap(flat_multiset& x, flat_multiset& y) noexcept + constexpr friend void swap(flat_multiset& x, flat_multiset& y) noexcept { x.swap(y); } private: @@ -17878,7 +19851,7 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); +constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -17890,23 +19863,25 @@ \pnum \complexity -Linear in $N$ if \tcode{cont} is sorted with respect to \exposid{compare} and +Linear in $N$ if \tcode{cont} is already sorted with respect to \exposid{compare} and otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. \end{itemdescr} +\rSec3[flat.multiset.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true}. + \indexlibraryctor{flat_multiset}% \begin{itemdecl} -template - flat_multiset(const container_type& cont, const Allocator& a); -template - flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a); +template + constexpr flat_multiset(const container_type& cont, const Alloc& a); +template + constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to \tcode{flat_multiset(cont)} and @@ -17922,22 +19897,18 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -template - flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a); -template - flat_multiset(sorted_equivalent_t s, const container_type& cont, - const key_compare& comp, const Allocator& a); +template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects -Equivalent to \tcode{flat_multiset(s, cont)} and -\tcode{flat_multiset(s, cont, comp)}, respectively, +Equivalent to \tcode{flat_multiset(sorted_equivalent, cont)} and +\tcode{flat_multiset(sorted_equivalent, cont, comp)}, respectively, except that \exposid{c} is constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -17948,44 +19919,42 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -template - flat_multiset(const flat_multiset&, const Allocator& a); -template - flat_multiset(flat_multiset&&, const Allocator& a); -template - flat_multiset(const key_compare& comp, const Allocator& a); -template - explicit flat_multiset(const Allocator& a); -template - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); -template - flat_multiset(InputIterator first, InputIterator last, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const Allocator& a); -template<@\exposconcept{container-compatible-range}@ R, class Allocator> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a); -template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Allocator& a); -template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a); -template - flat_multiset(initializer_list il, const key_compare& comp, const Allocator& a); -template - flat_multiset(initializer_list il, const Allocator& a); -template - flat_multiset(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Allocator& a); -template - flat_multiset(sorted_equivalent_t, initializer_list il, const Allocator& a); +template + constexpr explicit flat_multiset(const Alloc& a); +template + constexpr flat_multiset(const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(const flat_multiset&, const Alloc& a); +template + constexpr flat_multiset(flat_multiset&&, const Alloc& a); +template + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(initializer_list il, const Alloc& a); +template + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum -\constraints -\tcode{uses_allocator_v} is \tcode{true}. - \pnum \effects Equivalent to the corresponding non-allocator constructors @@ -17997,7 +19966,7 @@ \indexlibrarymember{emplace}{flat_multiset}% \begin{itemdecl} -template iterator emplace(Args&&... args); +template constexpr iterator emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -18011,8 +19980,8 @@ with \tcode{std::forward(args)...}, then inserts \tcode{t} as if by: \begin{codeblock} -auto it = ranges::upper_bound(c, t, compare); -c.insert(it, std::move(t)); +auto it = ranges::upper_bound(@\exposid{c}@, t, @\exposid{compare}@); +@\exposid{c}@.insert(it, std::move(t)); \end{codeblock} \pnum @@ -18023,7 +19992,7 @@ \indexlibrarymember{insert}{flat_multiset}% \begin{itemdecl} template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18031,7 +20000,7 @@ \effects Adds elements to \exposid{c} as if by: \begin{codeblock} -c.insert(c.end(), first, last); +@\exposid{c}@.insert(@\exposid{c}@.end(), first, last); \end{codeblock} Then, sorts the range of newly inserted elements with respect to \exposid{compare}, and merges the resulting sorted range and @@ -18050,7 +20019,7 @@ \indexlibrarymember{insert}{flat_multiset}% \begin{itemdecl} template - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18065,7 +20034,7 @@ \indexlibrarymember{swap}{flat_multiset}% \begin{itemdecl} -void swap(flat_multiset& y) noexcept; +constexpr void swap(flat_multiset& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -18073,14 +20042,14 @@ \effects Equivalent to: \begin{codeblock} -ranges::swap(compare, y.compare); -ranges::swap(c, y.c); +ranges::swap(@\exposid{compare}@, y.@\exposid{compare}@); +ranges::swap(@\exposid{c}@, y.@\exposid{c}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{extract}{flat_multiset}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -18090,12 +20059,12 @@ \pnum \returns -\tcode{std::move(c)}. +\tcode{std::move(\exposid{c})}. \end{itemdescr} \indexlibrarymember{replace}{flat_multiset}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -18105,7 +20074,7 @@ \pnum \effects -Equivalent to: \tcode{c = std::move(cont);} +Equivalent to: \tcode{\exposid{c} = std::move(cont);} \end{itemdescr} \rSec3[flat.multiset.erasure]{Erasure} @@ -18113,7 +20082,7 @@ \indexlibrarymember{erase_if}{flat_multiset}% \begin{itemdecl} template - typename flat_multiset::size_type + constexpr typename flat_multiset::size_type erase_if(flat_multiset& c, Predicate pred); \end{itemdecl} @@ -18211,8 +20180,8 @@ \rSec2[views.general]{General} \pnum -The header \libheader{span} defines the view \tcode{span}. -The header \libheader{mdspan} defines the class template \tcode{mdspan} and +The header \libheaderref{span} defines the view \tcode{span}. +The header \libheaderref{mdspan} defines the class template \tcode{mdspan} and other facilities for interacting with these multidimensional views. \rSec2[views.contiguous]{Contiguous access} @@ -18332,7 +20301,7 @@ // \ref{span.obs}, observers constexpr size_type size() const noexcept; constexpr size_type size_bytes() const noexcept; - [[nodiscard]] constexpr bool empty() const noexcept; + constexpr bool empty() const noexcept; // \ref{span.elem}, element access constexpr reference operator[](size_type idx) const; @@ -18398,6 +20367,7 @@ \pnum \ensures +%FIXME: Should "is \tcode{true}" be appended here? \tcode{size() == 0 \&\& data() == nullptr}. \end{itemdescr} @@ -18426,11 +20396,13 @@ \begin{itemize} \item \range{first}{first + count} is a valid range. \item \tcode{It} models \libconcept{contiguous_iterator}. -\item -If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{count} is equal to \tcode{extent}. \end{itemize} +\pnum +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{count == extent} is \tcode{true}. + \pnum \effects Initializes \exposid{data_} with \tcode{to_address(first)} and @@ -18466,14 +20438,16 @@ \pnum \expects \begin{itemize} -\item -If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{last - first} is equal to \tcode{extent}. \item \range{first}{last} is a valid range. \item \tcode{It} models \libconcept{contiguous_iterator}. \item \tcode{End} models \tcode{\libconcept{sized_sentinel_for}}. \end{itemize} +\pnum +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{(last - first) == extent} is \tcode{true}. + \pnum \effects Initializes \exposid{data_} with \tcode{to_address(first)} and @@ -18544,14 +20518,17 @@ \pnum \expects \begin{itemize} -\item If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{ranges::size(r)} is equal to \tcode{extent}. \item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and \tcode{ranges::\libconcept{sized_range}}. \item If \tcode{is_const_v} is \tcode{false}, \tcode{R} models \tcode{ranges::\libconcept{borrowed_range}}. \end{itemize} +\pnum +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{ranges::size(r) == extent} is \tcode{true}. + \pnum \effects Initializes \exposid{data_} with \tcode{ranges::data(r)} and @@ -18573,9 +20550,9 @@ \tcode{is_const_v} is \tcode{true}. \pnum -\expects -If \tcode{extent} is not equal to \tcode{dynamic_extent}, then -\tcode{il.size()} is equal to \tcode{extent}. +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{il.size() == extent} is \tcode{true}. \pnum \effects @@ -18613,9 +20590,9 @@ \end{itemize} \pnum -\expects +\hardexpects If \tcode{extent} is not equal to \tcode{dynamic_extent}, -then \tcode{s.size()} is equal to \tcode{extent}. +then \tcode{s.size() == extent} is \tcode{true}. \pnum \effects @@ -18685,7 +20662,7 @@ \tcode{Count <= Extent} is \tcode{true}. \pnum -\expects +\hardexpects \tcode{Count <= size()} is \tcode{true}. \pnum @@ -18705,7 +20682,7 @@ \tcode{Count <= Extent} is \tcode{true}. \pnum -\expects +\hardexpects \tcode{Count <= size()} is \tcode{true}. \pnum @@ -18729,7 +20706,7 @@ is \tcode{true}. \pnum -\expects +\hardexpects \begin{codeblock} Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset) \end{codeblock} @@ -18760,7 +20737,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{count <= size()} is \tcode{true}. \pnum @@ -18775,7 +20752,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{count <= size()} is \tcode{true}. \pnum @@ -18791,7 +20768,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \begin{codeblock} offset <= size() && (count == dynamic_extent || count <= size() - offset) \end{codeblock} @@ -18831,7 +20808,7 @@ \indexlibrarymember{span}{empty}% \begin{itemdecl} -[[nodiscard]] constexpr bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -18849,7 +20826,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{idx < size()} is \tcode{true}. \pnum @@ -18883,7 +20860,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{empty()} is \tcode{false}. \pnum @@ -18902,7 +20879,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{empty()} is \tcode{false}. \pnum @@ -19076,6 +21053,10 @@ template using dextents = @\seebelow@; + // \ref{mdspan.extents.dims}, alias template \tcode{dims} + template + using dims = @\seebelow@; + // \ref{mdspan.layout}, layout mapping struct layout_left; struct layout_right; @@ -19089,6 +21070,10 @@ template class default_accessor; + // \ref{mdspan.accessor.aligned}, class template \tcode{aligned_accessor} + template + class aligned_accessor; + // \ref{mdspan.mdspan}, class template \tcode{mdspan} template> @@ -19128,7 +21113,7 @@ The class template \tcode{extents} represents a multidimensional index space of rank equal to \tcode{sizeof...(Extents)}. -In subclause \iref{views}, +In \iref{views}, \tcode{extents} is used synonymously with multidimensional index space. \begin{codeblock} @@ -19534,12 +21519,28 @@ \tcode{E::index_type} denotes \tcode{IndexType}. \end{itemdescr} +\rSec4[mdspan.extents.dims]{Alias template \tcode{dims}} + +\indexlibraryglobal{dims}% +\begin{itemdecl} +template + using dims = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A type \tcode{E} that is a specialization of \tcode{extents} +such that \tcode{E::rank() == Rank \&\& E::rank() == E::rank_dynamic()} is \tcode{true}, and +\tcode{E::index_type} denotes \tcode{IndexType}. +\end{itemdescr} + \rSec3[mdspan.layout]{Layout mapping} \rSec4[mdspan.layout.general]{General} \pnum -In subclauses \ref{mdspan.layout.reqmts} and \ref{mdspan.layout.policy.reqmts}: +In \ref{mdspan.layout.reqmts} and \ref{mdspan.layout.policy.reqmts}: \begin{itemize} \item @@ -19566,7 +21567,7 @@ \end{itemize} \pnum -In subclauses \ref{mdspan.layout.reqmts} through \ref{mdspan.layout.stride}: +In \ref{mdspan.layout.reqmts} through \ref{mdspan.layout.stride}: \begin{itemize} \item Let \exposid{is-mapping-of} be the exposition-only variable template defined as follows: @@ -19913,13 +21914,13 @@ \end{codeblock} \pnum -Each of \tcode{layout_left}, \tcode{layout_right}, and \tcode{layout_stride} -meets the layout mapping policy requirements and is a trivial type. - -\pnum -Each specialization of -\tcode{layout_left_padded} and \tcode{layout_right_padded} -meets the layout mapping policy requirements and is a trivial type. +Each of \tcode{layout_left}, \tcode{layout_right}, and \tcode{layout_stride}, +as well as each specialization of +\tcode{layout_left_padded} and \tcode{layout_right_padded}, +meets the layout mapping policy requirements and is a trivially copyable type. +Furthermore, +\tcode{is_trivially_default_constructible_v} is \tcode{true} +for any such type \tcode{T}. \rSec4[mdspan.layout.left]{Class template \tcode{layout_left::mapping}} @@ -20055,7 +22056,7 @@ \indexlibraryctor{layout_left::mapping}% \begin{itemdecl} -template +template constexpr explicit(!is_convertible_v) mapping(const layout_right::mapping& other) noexcept; \end{itemdecl} @@ -20126,8 +22127,7 @@ \pnum \effects -Effects: Direct-non-list-initializes -\tcode{extents_} with \tcode{other.extents()}. +Direct-non-list-initializes \tcode{extents_} with \tcode{other.extents()}. \end{itemdescr} \indexlibraryctor{layout_left::mapping}% @@ -20211,7 +22211,7 @@ \indexlibrarymember{stride}{layout_left::mapping}% \begin{itemdecl} -constexpr index_type stride(rank_type i) const; +constexpr index_type stride(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -21254,9 +23254,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}. @@ -21360,7 +23360,7 @@ LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value \end{codeblock} -is true. +is \tcode{true}. \pnum \begin{itemize} @@ -21750,7 +23750,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} @@ -22225,7 +24225,7 @@ the accessor policy's \tcode{access} function produces a valid reference to an object. \pnum -In subclause \ref{mdspan.accessor.reqmts}, +In \ref{mdspan.accessor.reqmts}, \begin{itemize} \item @@ -22446,6 +24446,195 @@ Equivalent to: \tcode{return p + i;} \end{itemdescr} +\rSec4[mdspan.accessor.aligned]{Class template \tcode{aligned_accessor}} + +\rSec5[mdspan.accessor.aligned.overview]{Overview} + +\begin{codeblock} +namespace std { + template + struct @\libglobal{aligned_accessor}@ { + using offset_policy = default_accessor; + using element_type = ElementType; + using reference = ElementType&; + using data_handle_type = ElementType*; + + static constexpr size_t byte_alignment = ByteAlignment; + + constexpr aligned_accessor() noexcept = default; + template + constexpr aligned_accessor( + aligned_accessor) noexcept; + template + constexpr explicit aligned_accessor(default_accessor) noexcept; + + template + constexpr operator default_accessor() const noexcept; + + constexpr reference access(data_handle_type p, size_t i) const noexcept; + + constexpr typename offset_policy::data_handle_type offset( + data_handle_type p, size_t i) const noexcept; + }; +} +\end{codeblock} + +\pnum +\mandates +\begin{itemize} +\item \tcode{byte_alignment} is a power of two, and +\item \tcode{byte_alignment >= alignof(ElementType)} is \tcode{true}. +\end{itemize} + +\pnum +\tcode{aligned_accessor} meets the accessor policy requirements. + +\pnum +\tcode{ElementType} is required to be a complete object type +that is neither an abstract class type nor an array type. + +\pnum +Each specialization of \tcode{aligned_accessor} is +a trivially copyable type that models \libconcept{semiregular}. + +\pnum +\range{0}{$n$} is an accessible range +for an object \tcode{p} of type \tcode{data_handle_type} and +an object of type \tcode{aligned_accessor} if and only if +\begin{itemize} +\item +\range{p}{p + $n$} is a valid range, and, +\item +if $n$ is greater than zero, +then \tcode{is_sufficiently_aligned(p)} is \tcode{true}. +\end{itemize} + +\pnum +\begin{example} +The following function \tcode{compute} +uses \tcode{is_sufficiently_aligned} to check +whether a given \tcode{mdspan} with \tcode{default_accessor} has +a data handle with sufficient alignment +to be used with \tcode{aligned_accessor}. +If so, the function dispatches to +a function \tcode{compute_using_fourfold_overalignment} +that requires fourfold over-alignment of arrays, +but can therefore use hardware-specific instructions, +such as four-wide SIMD (Single Instruction Multiple Data) instructions. +Otherwise, \tcode{compute} dispatches to a +possibly less optimized function \tcode{compute_without_requiring_overalignment} +that has no over-alignment requirement. +\begin{codeblock} +void compute_using_fourfold_overalignment( + std::mdspan, std::layout_right, + std::aligned_accessor> x); + +void compute_without_requiring_overalignment( + std::mdspan, std::layout_right> x); + +void compute(std::mdspan> x) { + constexpr auto byte_alignment = 4 * sizeof(float); + auto accessor = std::aligned_accessor{}; + auto x_handle = x.data_handle(); + + if (std::is_sufficiently_aligned(x_handle)) { + compute_using_fourfold_overalignment(std::mdspan{x_handle, x.mapping(), accessor}); + } else { + compute_without_requiring_overalignment(x); + } +} +\end{codeblock} +\end{example} + +\rSec5[mdspan.accessor.aligned.members]{Members} + +\indexlibraryctor{aligned_accessor}% +\begin{itemdecl} +template + constexpr aligned_accessor(aligned_accessor) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} +is \tcode{true}. +\item +\tcode{OtherByteAlignment >= byte_alignment} is \tcode{true}. +\end{itemize} + +\pnum +\effects +None. +\end{itemdescr} + +\indexlibraryctor{aligned_accessor}% +\begin{itemdecl} +template + constexpr explicit aligned_accessor(default_accessor) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} +is \tcode{true}. + +\pnum +\effects +None. +\end{itemdescr} + +\indexlibrarymember{access}{aligned_accessor}% +\begin{itemdecl} +constexpr reference access(data_handle_type p, size_t i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. + +\pnum +\effects +Equivalent to: \tcode{return assume_aligned(p)[i];} +\end{itemdescr} + +\indexlibrarymember{operator default_accessor}{aligned_accessor}% +\begin{itemdecl} +template + constexpr operator default_accessor() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} +is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return \{\};} +\end{itemdescr} + +\indexlibrarymember{offset}{aligned_accessor}% +\begin{itemdecl} +constexpr typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. + +\pnum +\effects +Equivalent to: \tcode{return assume_aligned(p) + i;} +\end{itemdescr} + \rSec3[mdspan.mdspan]{Class template \tcode{mdspan}} \rSec4[mdspan.mdspan.overview]{Overview} @@ -22512,7 +24701,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; @@ -22533,7 +24722,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); } @@ -22857,17 +25046,16 @@ \pnum \expects -\begin{itemize} -\item -For each rank index \tcode{r} of \tcode{extents_type}, -\tcode{static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)} -is \tcode{true}. -\item $[0, \tcode{\exposid{map_}.required_span_size()})$ is an accessible range of \exposid{ptr_} and \exposid{acc_} for values of \exposid{ptr_}, \exposid{map_}, and \exposid{acc_} after the invocation of this constructor. -\end{itemize} + +\pnum +\hardexpects +For each rank index \tcode{r} of \tcode{extents_type}, +\tcode{static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)} +is \tcode{true}. \pnum \effects @@ -22913,7 +25101,7 @@ Let \tcode{I} be \tcode{extents_type::\exposid{index-cast}(std::move(indices))}. \pnum -\expects +\hardexpects \tcode{I} is a multidimensional index in \tcode{extents()}. \begin{note} This implies that @@ -22978,7 +25166,7 @@ \indexlibrarymember{empty}{mdspan}% \begin{itemdecl} -[[nodiscard]] constexpr bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -23016,7 +25204,7 @@ the \tcode{SliceSpecifier} arguments. \pnum -For each function defined in subclause \ref{mdspan.sub} that +For each function defined in \ref{mdspan.sub} that takes a parameter pack named \tcode{slices} as an argument: \begin{itemize} @@ -23412,9 +25600,26 @@ is \tcode{true}. \pnum -Let \tcode{offset} be a value of type \tcode{size_t} equal to +If \tcode{\exposid{first_}(slices...)} +equals \tcode{extents().extent($k$)} +for any rank index $k$ of \tcode{extents()}, then +let \tcode{offset} be a value of type \tcode{size_t} equal to +\tcode{(*this).required_span_size()}. +Otherwise, +let \tcode{offset} be a value of type \tcode{size_t} equal to \tcode{(*this)(\exposid{first_}(slices...)...)}. +\pnum +Given a layout mapping type \tcode{M}, a type \tcode{S} is a +\defnadjx{unit-stride}{slice for \tcode{M}}{slice} if +\begin{itemize} +\item \tcode{S} is a specialization of \tcode{strided_slice} +where \tcode{S::stride_type} models \exposconcept{integral-constant-like} +and \tcode{S::stride_type::value} equals \tcode{1}, +\item \tcode{S} models \tcode{\exposconcept{index-pair-like}}, or +\item \tcode{is_convertible_v} is \tcode{true}. +\end{itemize} + \rSec5[mdspan.sub.map.left]{\tcode{layout_left} specialization of \tcode{submdspan_mapping}} \indexlibrarymemberexpos{layout_left::mapping}{submdspan-mapping-impl}% @@ -23446,8 +25651,7 @@ \tcode{is_convertible_v<$S_k$, full_ext\-ent_t>} is \tcode{true}; and \item for $k$ equal to \tcode{SubExtents::rank() - 1}, - $S_k$ models \tcode{\exposconcept{index-pair-like}} or - \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; + $S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} \begin{note} If the above conditions are true, @@ -23462,21 +25666,17 @@ \end{codeblock} if for a value $u$ for which $u+1$ is the smallest value $p$ larger than zero -for which $S_p$ models -\tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_p$, full_extent_t>} is \tcode{true}, +for which $S_p$ is a unit-stride slice for \tcode{mapping}, the following conditions are met: \begin{itemize} \item -$S_0$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_0$, full_extent_t>} is \tcode{true}; and +$S_0$ is a unit-stride slice for \tcode{mapping}; and \item for each $k$ in the range \range{$u$ + 1}{$u$ + SubExtents::rank() - 1}, \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and \item for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; +$S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -23527,8 +25727,7 @@ \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and \item for $k$ equal to \exposid{_rank} - \tcode{SubExtents::rank()}, - $S_k$ models \tcode{\exposconcept{index-pair-like}} or - \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; + $S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} \begin{note} If the above conditions are true, @@ -23543,23 +25742,19 @@ \end{codeblock} if for a value $u$ for which $\exposid{rank_} - u - 2$ is the largest value $p$ smaller than \tcode{\exposid{rank_} - 1} -for which $S_p$ models -\tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_p$, full_extent_t>} is \tcode{true}, +for which $S_p$ is a unit-stride slice for \tcode{mapping}, the following conditions are met: \begin{itemize} \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$, full_extent_t> }is \tcode{true}; and +$S_k$ is a unit-stride slice for \tcode{mapping}; and \item for each $k$ in the range \range{\exposid{rank_} - SubExtents::rank() - $u$ + 1}{\exposid{rank_} - $u$ - 1}, \tcode{is_con\-vertible_v<$S_k$, full_extent_t>} is \tcode{true}; and \item -for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; +for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$},\newline +$S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -23635,8 +25830,7 @@ \item \tcode{SubExtents::rank() == 1} is \tcode{true} and \item -$S_0$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_0$ , full_extent_t>} is \tcode{true}; +$S_0$ is a unit-stride slice for \tcode{mapping}; \end{itemize} \item otherwise, @@ -23646,20 +25840,17 @@ \end{codeblock} if for a value $u$ for which \tcode{$u$ + 1} is the smallest value $p$ larger than zero -for which $S_p$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_p$, full_extent_t>} is \tcode{true}, +for which $S_p$ is a unit-stride slice for \tcode{mapping}, the following conditions are met: \begin{itemize} \item -$S_0$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_0$, full_extent_t>} is \tcode{true}; and +$S_0$ is a unit-stride slice for \tcode{mapping}; and \item for each $k$ in the range \range{$u$ + 1}{$u$ + SubExtents::rank() - 1}, \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and \item for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v} is \tcode{true}; +$S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} where \tcode{S_static} is: \begin{itemize} @@ -23711,8 +25902,7 @@ \tcode{SubExtents::rank() == 1} is \tcode{true} and \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$ , full_extent_t>} is \tcode{true}; +$S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} \item otherwise, @@ -23723,22 +25913,19 @@ if for a value $u$ for which \tcode{\exposid{rank_} - $u$ - 2} is the largest value p smaller than \tcode{\exposid{rank_} - 1} -for which $S_p$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_p$, full_extent_t>} is \tcode{true}, +for which $S_p$ is a unit-stride slice for \tcode{mapping}, the following conditions are met: \begin{itemize} \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and +$S_k$ is a unit-stride slice for \tcode{mapping}; and \item for each $k$ in the range \range{\exposid{rank_} - SubExtents::rank() - $u$ + 1}{\exposid{rank_} - $u$ - 1)}, \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and \item -for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$}, -$S_k$ models \tcode{\exposconcept{index-pair-like}} or -\tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; +for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$},\newline +$S_k$ is a unit-stride slice for \tcode{mapping}; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -23860,9 +26047,9 @@ \effects Equivalent to: \begin{codeblock} -auto sub_map_offset = submdspan_mapping(src.mapping(), slices...); -return mdspan(src.accessor().offset(src.data(), sub_map_offset.offset), - sub_map_offset.mapping, +auto sub_map_result = submdspan_mapping(src.mapping(), slices...); +return mdspan(src.accessor().offset(src.data(), sub_map_result.offset), + sub_map_result.mapping, AccessorPolicy::offset_policy(src.accessor())); \end{codeblock} \end{itemdescr} diff --git a/source/cover-reg.tex b/source/cover-reg.tex index 91e968e150..5923fce26d 100644 --- a/source/cover-reg.tex +++ b/source/cover-reg.tex @@ -59,15 +59,16 @@ \thispagestyle{cpppage} -\fbox{% -\begin{minipage}{\copyboxwidth} +\vspace*{\fill} + \vspace{1ex} -\begin{center} -\textbf{Copyright notice} -\end{center} +\raisebox{-1ex}{\includegraphics{assets/iso-logo-caution.png}}\qquad{\Large{\textbf{COPYRIGHT PROTECTED DOCUMENT}}} \vspace{2ex} +\isocopyright + All rights reserved. Unless otherwise specified, +or required in the context of its implementation, no part of this publication may be reproduced or utilized otherwise in any form or by any means, electronic or mechanical, including photocopying, @@ -75,17 +76,18 @@ without prior written permission. Permission can be requested from either ISO at the address below -or ISO's member body in the country of the requester.\\\\ +or ISO's member body in the country of the requester. \begin{indented} \microtypesetup{activate=false}% ISO copyright office\\ -Case postale 56, CH-1211 Geneva 20\\ -\rlap{Tel.}\hphantom{Fax} + 41 22 749 01 11\\ -Fax + 41 22 749 09 47\\ -E-mail \texttt{copyright@iso.org}\\ -Web \url{www.iso.org} +CP 401 \textbullet{} Ch.\ de Blandonnet 8\\ +CH-1214 Vernier, Geneva\\ +Phone: +41 22 749 01 11\\ +Email: \texttt{copyright@iso.org}\\ +Website: \url{www.iso.org} \end{indented} -\end{minipage}} + +Published in Switzerland \newpage diff --git a/source/declarations.tex b/source/declarations.tex index 2079217bac..020161723b 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1,5 +1,5 @@ %!TEX root = std.tex -\rSec0[dcl.dcl]{Declarations}% +\rSec0[dcl]{Declarations}% \indextext{declaration|(} \gramSec[gram.dcl]{Declarations} @@ -13,8 +13,7 @@ the form \begin{bnf} \nontermdef{declaration-seq}\br - declaration\br - declaration-seq declaration + declaration \opt{declaration-seq} \end{bnf} \begin{bnf} @@ -69,19 +68,19 @@ \end{bnf} \begin{bnf} -\nontermdef{attributed-identifier}\br - identifier \opt{attribute-specifier-seq} +\nontermdef{sb-identifier}\br + \opt{\terminal{...}} identifier \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} -\nontermdef{attributed-identifier-list}\br - attributed-identifier\br - attributed-identifier-list \terminal{,} attributed-identifier +\nontermdef{sb-identifier-list}\br + sb-identifier\br + sb-identifier-list \terminal{,} sb-identifier \end{bnf} \begin{bnf} \nontermdef{structured-binding-declaration}\br - \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} attributed-identifier-list \terminal{]} + \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} sb-identifier-list \terminal{]} \end{bnf} \begin{bnf} @@ -129,7 +128,7 @@ \indextext{scope}% Certain declarations contain one or more scopes\iref{basic.scope.scope}. Unless otherwise stated, utterances in -\ref{dcl.dcl} about components in, of, or contained by a +\ref{dcl} about components in, of, or contained by a declaration or subcomponent thereof refer only to those components of the declaration that are \emph{not} nested within scopes nested within the declaration. @@ -208,14 +207,21 @@ \end{example} \pnum -A \grammarterm{simple-declaration} with a \grammarterm{structured-binding-declaration} is called +A \grammarterm{simple-declaration} or a \grammarterm{condition} +with a \grammarterm{structured-binding-declaration} is called a \defn{structured binding declaration}\iref{dcl.struct.bind}. Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} shall be +\tcode{constexpr}, +\tcode{constinit}, \tcode{static}, \tcode{thread_local}, \tcode{auto}\iref{dcl.spec.auto}, or a \grammarterm{cv-qualifier}. +The declaration shall contain at most one \grammarterm{sb-identifier} +whose \grammarterm{identifier} is preceded by an ellipsis. +If the declaration contains any such \grammarterm{sb-identifier}, +it shall declare a templated entity\iref{temp.pre}. \begin{example} \begin{codeblock} template concept C = true; @@ -227,9 +233,13 @@ of the form ``\tcode{=} \grammarterm{assignment-expression}'', of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'', or -of the form ``\tcode{(} \grammarterm{assignment-expression} \tcode{)}'', -where the -\grammarterm{assignment-expression} is of array or non-union class type. +of the form ``\tcode{(} \grammarterm{assignment-expression} \tcode{)}''. +If the \grammarterm{structured-binding-declaration} appears as +a \grammarterm{condition}, +the \grammarterm{assignment-expression} shall be of non-union class type. +Otherwise, +the \grammarterm{assignment-expression} shall be of +array or non-union class type. \pnum If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef} @@ -256,16 +266,29 @@ \end{codeblock} \end{example} +\pnum +\indextext{initialization!definition and}% +An object definition causes +storage of appropriate size and alignment to be reserved and +any appropriate initialization\iref{dcl.init} to be done. + \pnum \indextext{definition!declaration as}% Syntactic components beyond those found in the general form of \grammarterm{simple-declaration} are added to a function declaration to make a -\grammarterm{function-definition}. An object declaration, however, is also -a definition unless it contains the \keyword{extern} specifier and has no -initializer\iref{basic.def}. -\indextext{initialization!definition and}% -An object definition causes storage of appropriate size and alignment to be reserved and -any appropriate initialization\iref{dcl.init} to be done. +\grammarterm{function-definition}. +A token sequence starting with \tcode{\{} or \tcode{=} +is treated as a \grammarterm{function-body}\iref{dcl.fct.def.general} +if the type of the \grammarterm{declarator-id}\iref{dcl.meaning.general} +is a function type, and +is otherwise +treated as a \grammarterm{brace-or-equal-initializer}\iref{dcl.init.general}. +\begin{note} +If the declaration acquires a function type through template instantiation, +the program is ill-formed; see \ref{temp.spec.general}. +The function type of a function definition +cannot be specified with a \grammarterm{typedef-name}\iref{dcl.fct}. +\end{note} \pnum A \grammarterm{nodeclspec-function-declaration} shall declare a @@ -400,9 +423,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}. @@ -633,6 +656,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 @@ -752,7 +778,7 @@ \indextext{class name!\idxcode{typedef}}% A \grammarterm{simple-template-id} is only a \grammarterm{typedef-name} if its \grammarterm{template-name} names -an alias template or a template \grammarterm{template-parameter}. +an alias template or a type template template parameter. \begin{note} A \grammarterm{simple-template-id} that names a class template specialization is a \grammarterm{class-name}\iref{class.name}. @@ -829,7 +855,8 @@ \pnum The \keyword{constexpr} specifier shall be applied only to -the definition of a variable or variable template or +the definition of a variable or variable template, +a structured binding declaration, or the declaration of a function or function template. The \keyword{consteval} specifier shall be applied only to the declaration of a function or function template. @@ -888,7 +915,7 @@ \pnum \indextext{specifier!\idxcode{constexpr}!function}% \indextext{constexpr function}% -A function is \defn{constexpr-suitable} if: +A function is \defn{constexpr-suitable} if \begin{itemize} \item it is not a coroutine\iref{dcl.fct.def.coroutine}, and @@ -974,9 +1001,7 @@ Such an object shall have literal type and shall be initialized. -In any \keyword{constexpr} variable declaration, -the full-expression of the initialization -shall be a constant expression\iref{expr.const}. +A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const}. A \keyword{constexpr} variable that is an object, as well as any temporary to which a \keyword{constexpr} reference is bound, shall have constant destruction. @@ -987,6 +1012,16 @@ }; constexpr pixel ur = { 1294, 1024 }; // OK constexpr pixel origin; // error: initializer missing + +namespace N { + void f() { + int x; + constexpr int& ar = x; // OK + static constexpr int& sr = x; // error: \tcode{x} is not constexpr-representable + // at the point indicated below + } + // immediate scope here is that of \tcode{N} +} \end{codeblock} \end{example} @@ -995,7 +1030,12 @@ \pnum The \keyword{constinit} specifier shall be applied only -to a declaration of a variable with static or thread storage duration. +to a declaration of a variable with static or thread storage duration +or to a structured binding declaration\iref{dcl.struct.bind}. +\begin{note} +A structured binding declaration introduces a uniquely named variable, +to which the \tcode{constinit} specifier applies. +\end{note} If the specifier is applied to any declaration of a variable, it shall be applied to the initializing declaration. No diagnostic is required if no \keyword{constinit} declaration @@ -1237,7 +1277,7 @@ \pnum \indextext{const object!undefined change to}% -Any attempt to modify\iref{expr.ass,expr.post.incr,expr.pre.incr} a +Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a const object\iref{basic.type.qualifier} during its lifetime\iref{basic.life} results in undefined behavior. \begin{example} @@ -1512,8 +1552,10 @@ \indextext{name!elaborated!\idxcode{enum}}% If an \grammarterm{elaborated-type-specifier} is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit -specialization\iref{temp.expl.spec}, an explicit -instantiation\iref{temp.explicit} or it has one of the following +specialization\iref{temp.expl.spec}, +a partial specialization\iref{temp.spec.partial}, +an explicit +instantiation\iref{temp.explicit}, or it has one of the following forms: \begin{ncsimplebnf} @@ -1527,7 +1569,7 @@ The second case shall appear only in an \grammarterm{explicit-specialization}\iref{temp.expl.spec} or in a \grammarterm{template-declaration} -(where it declares a partial specialization\iref{temp.decls}). +(where it declares a partial specialization). The \grammarterm{attribute-specifier-seq}, if any, appertains to the class or template being declared. @@ -1584,7 +1626,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 @@ -1629,8 +1671,8 @@ the specification of the structured binding declaration; \item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} -naming a non-type \grammarterm{template-parameter}\iref{temp.param}, -\tcode{decltype($E$)} is the type of the \grammarterm{template-parameter} +naming a constant template parameter\iref{temp.param}, +\tcode{decltype($E$)} is the type of the template parameter after performing any necessary type deduction\iref{dcl.spec.auto,dcl.type.class.deduct}; @@ -1748,9 +1790,11 @@ \pnum The type of a \grammarterm{parameter-declaration} of a -function declaration\iref{dcl.fct}, -\grammarterm{lambda-expression}\iref{expr.prim.lambda}, or -\grammarterm{template-parameter}\iref{temp.param} +\begin{itemize} + \item function declaration\iref{dcl.fct}, + \item \grammarterm{lambda-expression}\iref{expr.prim.lambda}, or + \item \grammarterm{template-parameter}\iref{temp.param} +\end{itemize} can be declared using a \grammarterm{placeholder-type-specifier} of the form \opt{\grammarterm{type-constraint}} \keyword{auto}. @@ -1906,6 +1950,20 @@ \end{codeblock} \end{example} +\pnum +A result binding never has +an undeduced placeholder type\iref{dcl.contract.res}. +\begin{example} +\begin{codeblock} +auto f() + post(r : r == 7) // OK +{ + return 7; +} +\end{codeblock} +\end{example} + + \pnum Return type deduction for a templated function with a placeholder in its @@ -2062,9 +2120,9 @@ and $E$ is the \grammarterm{assignment-expression}. \end{itemize} \item -For a non-type template parameter declared with a type +For a constant template parameter declared with a type that contains a placeholder type, -\tcode{T} is the declared type of the non-type template parameter +\tcode{T} is the declared type of the constant template parameter and $E$ is the corresponding template argument. \end{itemize} @@ -2238,8 +2296,8 @@ \begin{bnf} \nontermdef{init-declarator}\br - declarator \opt{initializer}\br - declarator requires-clause + declarator initializer\br + declarator \opt{requires-clause} \opt{function-contract-specifier-seq} \end{bnf} \pnum @@ -2331,6 +2389,12 @@ \end{codeblock} \end{example} +\pnum +The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func} +in an \grammarterm{init-declarator} +shall be present only if +the \grammarterm{declarator} declares a function. + \pnum Declarators have the syntax @@ -2366,7 +2430,7 @@ \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{ptr-operator}\br \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br \terminal{\&} \opt{attribute-specifier-seq}\br @@ -2963,7 +3027,7 @@ \end{example} \pnum -See also~\ref{expr.ass} and~\ref{dcl.init}. +See also~\ref{expr.assign} and~\ref{dcl.init}. \pnum \begin{note} @@ -3568,21 +3632,21 @@ 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 - \opt{parameter-declaration-list} \opt{\terminal{...}}\br - parameter-declaration-list \terminal{,} \terminal{...} + \terminal{...}\br + \opt{parameter-declaration-list}\br + parameter-declaration-list \terminal{,} \terminal{...}\br + parameter-declaration-list \terminal{...} \end{bnf} \begin{bnf} @@ -3618,7 +3682,7 @@ If the \grammarterm{parameter-declaration-clause} is empty, the function takes no arguments. -A parameter list consisting of a single unnamed parameter of +A parameter list consisting of a single unnamed non-object parameter of non-dependent type \keyword{void} is equivalent to an empty parameter list. \indextext{parameter!\idxcode{void}}% @@ -3638,9 +3702,13 @@ argument and are not function parameter packs. Where syntactically correct and where ``\tcode{...}'' is not part of an \grammarterm{abstract-declarator}, -``\tcode{, ...}'' +``\tcode{...}'' is synonymous with -``\tcode{...}''. +``\tcode{, ...}''. +A \grammarterm{parameter-declaration-clause} +of the form +\grammarterm{parameter-declaration-list} \tcode{...} +is deprecated\iref{depr.ellipsis.comma}. \begin{example} The declaration \begin{codeblock} @@ -3973,7 +4041,7 @@ An abbreviated function template is equivalent to a function template\iref{temp.fct} whose \grammarterm{template-parameter-list} includes -one invented type \grammarterm{template-parameter} +one invented \grammarterm{type-parameter} for each generic parameter type placeholder of the function declaration, in order of appearance. For a \grammarterm{placeholder-type-specifier} of the form \keyword{auto}, @@ -3983,7 +4051,7 @@ \grammarterm{type-constraint} \keyword{auto}, the invented parameter is a \grammarterm{type-parameter} with that \grammarterm{type-constraint}. -The invented type \grammarterm{template-parameter} is +The invented \grammarterm{type-parameter} declares a template parameter pack if the corresponding \grammarterm{parameter-declaration} declares a function parameter pack. @@ -3992,7 +4060,7 @@ The adjusted function parameters of an abbreviated function template are derived from the \grammarterm{parameter-declaration-clause} by replacing each occurrence of a placeholder with -the name of the corresponding invented \grammarterm{template-parameter}. +the name of the corresponding invented \grammarterm{type-parameter}. \begin{example} \begin{codeblock} template concept C1 = /* ... */; @@ -4020,7 +4088,7 @@ \pnum An abbreviated function template can have a \grammarterm{template-head}. -The invented \grammarterm{template-parameter}{s} are +The invented \grammarterm{type-parameter}{s} are appended to the \grammarterm{template-parameter-list} after the explicitly declared \grammarterm{template-parameter}{s}. \begin{example} @@ -4401,6 +4469,326 @@ \indextext{declaration!default argument|)}% \indextext{declarator!meaning of|)} +\rSec1[dcl.contract]{Function contract specifiers} +\rSec2[dcl.contract.func]{General} + +\indextext{contract assertion!function|(}% + +\begin{bnf} +\nontermdef{function-contract-specifier-seq}\br + function-contract-specifier \opt{function-contract-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{function-contract-specifier}\br + precondition-specifier\br + postcondition-specifier +\end{bnf} + +\begin{bnf} +\nontermdef{precondition-specifier}\br + \terminal{pre} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{postcondition-specifier}\br + \terminal{post} \opt{attribute-specifier-seq} \terminal{(} \opt{result-name-introducer} conditional-expression \terminal{)} +\end{bnf} + +\pnum +\indexdefn{contract assertion!postcondition|see{assertion, postcondition}} +\indexdefn{contract assertion!precondition|see{assertion, precondition}} +A \defnadj{function}{contract assertion} +is a contract assertion\iref{basic.contract.general} +associated with a function. +A \grammarterm{precondition-specifier} +introduces a \defnadj{precondition}{assertion}, +which is a function contract assertion +associated with entering a function. +A \grammarterm{postcondition-specifier} +introduces a \defnadj{postcondition}{assertion}, +which is a function contract assertion +associated with exiting a function normally. +\begin{note} +A postcondition assertion +is not associated with exiting a function +in any other fashion, +such as via an exception\iref{expr.throw} +or via a call to \tcode{longjmp}\iref{csetjmp.syn}. +\end{note} + +\pnum +The predicate\iref{basic.contract.general} +of a function contract assertion +is its \grammarterm{conditional-expression} +contextually converted to \tcode{bool}. + +\pnum +Each \grammarterm{function-contract-specifier} +of a \grammarterm{function-contract-specifier-seq} (if any) +of an unspecified first declaration\iref{basic.def} +of a function +introduces a corresponding function contract assertion for that function. +The optional \grammarterm{attribute-specifier-seq} +following \tcode{pre} or \tcode{post} +appertains to the introduced contract assertion. +\begin{note} +The \grammarterm{function-contract-specifier-seq} +of a \grammarterm{lambda-declarator} +applies to the function call operator or operator template +of the corresponding closure type\iref{expr.prim.lambda.closure}. +\end{note} + +\pnum +A declaration $D$ +of a function or function template \placeholder{f} +that is not a first declaration shall have either +no \grammarterm{function-contract-specifier-seq} +or the same \grammarterm{function-contract-specifier-seq} (see below) +as any first declaration $F$ reachable from $D$. +If $D$ and $F$ are +in different translation units, +a diagnostic is required only if $D$ is attached to a named module. +If a declaration $F_1$ is a +first declaration of \tcode{f} +in one translation unit and +a declaration $F_2$ is a +first declaration of \tcode{f} in another translation unit, +$F_1$ and $F_2$ shall specify the same +\grammarterm{function-contract-specifier-seq}, no diagnostic required. + +\pnum +A \grammarterm{function-contract-specifier-seq} $S_1$ +is the same as +a \grammarterm{function-contract-specifier-seq} $S_2$ +if $S_1$ and $S_2$ consist of +the same \grammarterm{function-contract-specifier}s +in the same order. +A \grammarterm{function-contract-specifier} $C_1$ +on a function declaration $D_1$ is +the same as +a \grammarterm{function-contract-specifier} $C_2$ +on a function declaration $D_2$ +if +\begin{itemize} +\item +their predicates $P_1$ and $P_2$ would +satisfy the one-definition rule\iref{basic.def.odr} +if placed in function definitions on +the declarations $D_1$ and $D_2$, respectively, except for +\begin{itemize} +\item +renaming of the parameters of \placeholder{f}, +\item +renaming of template parameters of +a template enclosing \placeholder{}, and +\item +renaming of the result binding\iref{dcl.contract.res}, if any, +\end{itemize} +and, +if $D_1$ and $D_2$ are in different translation units, +corresponding entities defined within each predicate +behave as if there is a single entity with a single definition, and +\item +both $C_1$ and $C_2$ +specify a \grammarterm{result-name-introducer} +or neither do. +\end{itemize} +If this condition is not met +solely due to the comparison of two \grammarterm{lambda-expression}s +that are contained within $P_1$ and $P_2$, +no diagnostic is required. + +\begin{note} +Equivalent +\grammarterm{function-contract-specifier-seq}s +apply to all uses and definitions +of a function across all translation units. +\end{note} +\begin{example} +\begin{codeblock} + +bool b1, b2; + +void f() pre (b1) pre ([]{ return b2; }()); +void f(); // OK, \grammarterm{function-contract-specifier}s omitted +void f() pre (b1) pre ([]{ return b2; }()); // error: closures have different types. +void f() pre (b1); // error: \grammarterm{function-contract-specifier}s only partially repeated + +int g() post(r : b1); +int g() post(b1); // error: mismatched \grammarterm{result-name-introducer} presence + +namespace N { + void h() pre (b1); + bool b1; + void h() pre (b1); // error: \grammarterm{function-contract-specifier}s differ according to + // the one-definition rule\iref{basic.def.odr}. +} +\end{codeblock} +\end{example} + +\pnum +A virtual function\iref{class.virtual}, +a deleted function\iref{dcl.fct.def.delete}, +or a function defaulted on its first declaration\iref{dcl.fct.def.default} +shall not have a \grammarterm{function-contract-specifier-seq}. + +\pnum +If the predicate of a postcondition assertion +of a function \placeholder{f} +odr-uses\iref{basic.def.odr} +a non-reference parameter of \placeholder{f}, +that parameter +and the corresponding parameter on all declarations of \placeholder{f} +shall have \keyword{const} type. +\begin{note} +This requirement applies +even to declarations that do not specify the \grammarterm{postcondition-specifier}. +Parameters with array or function type +will decay to non-\keyword{const} types +even if a \keyword{const} qualifier is present. +\begin{example} +\begin{codeblock} +int f(const int i[10]) + post(r : r == i[0]); // error: \tcode{i} has type \tcode{const int *} (not \tcode{int* const}). +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +The function contract assertions of a function +are evaluated even when invoked indirectly, +such as through a pointer to function or a pointer to member function. +A pointer to function, +pointer to member function, +or function type alias +cannot have a \grammarterm{function-contract-specifier-seq} +associated directly with it. +\end{note} + +\pnum +The function contract assertions of a function +are considered to be \defnx{needed}{needed!function contract assertion}\iref{temp.inst} when +\begin{itemize} +\item +the function is odr-used\iref{basic.def.odr} or +\item +the function is defined. +\end{itemize} +\begin{note} +Overload resolution does not consider +\grammarterm{function-contract-specifier}s\iref{temp.deduct,temp.inst}. +\begin{example} +\begin{codeblock} +template void f(T t) pre( t == "" ); +template void f(T&& t); +void g() +{ + f(5); // error: ambiguous +} +\end{codeblock} +\end{example} +\end{note} + + +\rSec2[dcl.contract.res]{Referring to the result object} + +\begin{bnf} +\nontermdef{attributed-identifier}\br + identifier \opt{attribute-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{result-name-introducer}\br + attributed-identifier \terminal{:} +\end{bnf} + +\pnum +The \grammarterm{result-name-introducer} +of a \grammarterm{postcondition-specifier} +is a declaration. +The \grammarterm{result-name-introducer} +introduces the \grammarterm{identifier} +as the name of a \defn{result binding} +of the associated function. +If a postcondition assertion has a \grammarterm{result-name-introducer} +and the return type of the function is \cv{} \keyword{void}, +the program is ill-formed. +A result binding denotes +the object or reference returned by +invocation of that function. +The type of a result binding +is the return type of its associated function +The optional \grammarterm{attribute-specifier-seq} +of the \grammarterm{attributed-identifier} +in the \grammarterm{result-name-introducer} +appertains to the result binding so introduced. +\begin{note} +An \grammarterm{id-expression} +that names a result binding is a \keyword{const} lvalue\iref{expr.prim.id.unqual}. +\end{note} + +\begin{example} +\begin{codeblock} +int f() + post(r : r == 1) +{ + return 1; +} +int i = f(); // Postcondition check succeeds. +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct A {}; +struct B { + B() {} + B(const B&) {} +}; + +template +T f(T* const ptr) + post(r: &r == ptr) +{ + return {}; +} + +int main() { + A a = f(&a); // The postcondition check can fail if the implementation introduces + // a temporary for the return value\iref{class.temporary}. + B b = f(&b); // The postcondition check succeeds, no temporary is introduced. +} +\end{codeblock} +\end{example} + + +\pnum +When the declared return type +of a non-templated function +contains a placeholder type, +a \grammarterm{postcondition-specifier} +with a \grammarterm{result-name-introducer} +shall be present only on a definition. +\begin{example} +\begin{codeblock} +auto g(auto&) + post (r: r >= 0); // OK, \tcode{g} is a template. + +auto h() + post (r: r >= 0); // error: cannot name the return value + +auto k() + post (r: r >= 0) // OK +{ + return 0; +} +\end{codeblock} +\end{example} + +\indextext{contract assertion!function|)}% + \rSec1[dcl.init]{Initializers}% \rSec2[dcl.init.general]{General}% @@ -4629,15 +5017,10 @@ If \tcode{T} is a (possibly cv-qualified) class type\iref{class}, then -\begin{itemize} -\item -if \tcode{T} has -either no default constructor\iref{class.default.ctor} or a default -constructor that is user-provided or deleted, then the object is default-initialized; -\item -otherwise, -the object is zero-initialized and then default-initialized. -\end{itemize} +let \tcode{C} be the constructor selected to +default-initialize the object, if any. +If \tcode{C} is not user-provided, the object is first zero-initialized. +In all cases, the object is then default-initialized. \item If @@ -4659,7 +5042,7 @@ \pnum \begin{note} -For every object of static storage duration, +For every object with static storage duration, static initialization\iref{basic.start.static} is performed at program startup before any other initialization takes place. In some cases, additional initialization is done later. @@ -4708,7 +5091,7 @@ The \indextext{type!destination}% \term{destination type} -is the type of the object or reference being initialized and the +is the cv-unqualified type of the object or reference being initialized and the \term{source type} is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the @@ -4769,13 +5152,13 @@ is sequenced before those associated with the initialization of the $j^\text{th}$ element. \item -Otherwise, if the destination type is a (possibly cv-qualified) class type: +Otherwise, if the destination type is a class type: \begin{itemize} \item If the initializer expression is a prvalue and the cv-unqualified version of the source type -is the same class as the class of the destination, +is the same as the destination type, the initializer expression is used to initialize the destination object. \begin{example} \tcode{T x = T(T(T()));} value-initializes \tcode{x}. @@ -4783,7 +5166,7 @@ \item Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source -type is the same class as, or a derived class of, the class of the destination, +type is the same as or is derived from the class of the destination type, constructors are considered. The applicable constructors are enumerated\iref{over.match.ctor}, and the best one is chosen @@ -4880,7 +5263,7 @@ the (possibly converted) value of the initializer expression. A standard conversion sequence\iref{conv} is used to convert the initializer expression to -a prvalue of the cv-unqualified version of +a prvalue of the destination type; no user-defined conversions are considered. If the conversion cannot @@ -5641,7 +6024,7 @@ A reference cannot be changed to refer to another object after initialization. \indextext{assignment!reference}% \begin{note} -Assignment to a reference assigns to the object referred to by the reference\iref{expr.ass}. +Assignment to a reference assigns to the object referred to by the reference\iref{expr.assign}. \end{note} \indextext{argument passing!reference and}% Argument passing\iref{expr.call} @@ -5792,6 +6175,10 @@ return x; } constexpr int z = f(); // error: not a constant expression + +typedef int *A[3]; // array of 3 pointer to \tcode{int} +typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} +ACPC &&r = AP{}; // binds directly \end{codeblock} \end{example} @@ -5882,17 +6269,17 @@ \begin{note} List-initialization can be used \begin{itemize} -\item as the initializer in a variable definition\iref{dcl.init} -\item as the initializer in a \grammarterm{new-expression}\iref{expr.new} -\item in a \tcode{return} statement\iref{stmt.return} -\item as a \grammarterm{for-range-initializer}\iref{stmt.iter} -\item as a function argument\iref{expr.call} -\item as a template argument\iref{temp.arg.nontype} -\item as a subscript\iref{expr.sub} -\item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv} -\item as an initializer for a non-static data member\iref{class.mem} -\item in a \grammarterm{mem-initializer}\iref{class.base.init} -\item on the right-hand side of an assignment\iref{expr.ass} +\item as the initializer in a variable definition\iref{dcl.init}, +\item as the initializer in a \grammarterm{new-expression}\iref{expr.new}, +\item in a \tcode{return} statement\iref{stmt.return}, +\item as a \grammarterm{for-range-initializer}\iref{stmt.iter}, +\item as a function argument\iref{expr.call}, +\item as a template argument\iref{temp.arg.nontype}, +\item as a subscript\iref{expr.sub}, +\item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv}, +\item as an initializer for a non-static data member\iref{class.mem}, +\item in a \grammarterm{mem-initializer}\iref{class.base.init}, or +\item on the right-hand side of an assignment\iref{expr.assign}. \end{itemize} \begin{example} @@ -5984,7 +6371,7 @@ \item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a default constructor, the object is value-initialized. -\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, +\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, the object is constructed as described below. \item Otherwise, if \tcode{T} is a class type, constructors are considered. @@ -6263,10 +6650,9 @@ \item from a floating-point type \tcode{T} to another floating-point type whose floating-point conversion rank is neither greater than nor equal to that of \tcode{T}, -except where the source is a constant expression and -the actual value after conversion -is within the range of values that can be represented (even if it cannot be represented exactly), -or +except where the result of the conversion is a constant expression and +either its value is finite and the conversion did not overflow, or +the values before and after the conversion are not finite, or \item from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit @@ -6323,7 +6709,7 @@ \rSec1[dcl.fct.def]{Function definitions}% \indextext{definition!function|(} -\rSec2[dcl.fct.def.general]{In general} +\rSec2[dcl.fct.def.general]{General} \pnum \indextext{body!function}% @@ -6332,8 +6718,10 @@ % \begin{bnf} \nontermdef{function-definition}\br - \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq} function-body\br - \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause function-body + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq}\br + \bnfindent \opt{function-contract-specifier-seq} function-body\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause\br + \bnfindent \opt{function-contract-specifier-seq} function-body \end{bnf} \begin{bnf} @@ -6763,7 +7151,13 @@ as described below. \pnum -A coroutine behaves as if its \grammarterm{function-body} were replaced by: +A coroutine behaves as if +the top-level cv-qualifiers in all +\grammarterm{parameter-declaration}s in the declarator +of its \grammarterm{function-definition} +were removed and +its \grammarterm{function-body} were replaced by +the following \defnadj{replacement}{body}: \begin{ncsimplebnf} \terminal{\{}\br \bnfindent \placeholder{promise-type} \exposid{promise} \placeholder{promise-constructor-arguments} \terminal{;}\br @@ -6828,6 +7222,13 @@ \end{itemize} \end{itemize} +\pnum +\begin{note} +An odr-use of a non-reference parameter +in a postcondition assertion +of a coroutine is ill-formed\iref{dcl.contract.func}. +\end{note} + \pnum If searches for the names \tcode{return_void} and \tcode{return_value} in the scope of the promise type each find any declarations, @@ -6861,7 +7262,8 @@ \pnum An implementation may need to allocate additional storage for a coroutine. This storage is known as the \defn{coroutine state} and is obtained by calling -a non-array allocation function\iref{basic.stc.dynamic.allocation}. +a non-array allocation function\iref{basic.stc.dynamic.allocation} +as part of the replacement body. The allocation function's name is looked up by searching for it in the scope of the promise type. \begin{itemize} \item @@ -6869,7 +7271,9 @@ overload resolution is performed on a function call created by assembling an argument list. The first argument is the amount of space requested, and is a prvalue of type \tcode{std::size_t}. -The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ are the successive arguments. +The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ +with their original types (including cv-qualifiers) +are the successive arguments. If no viable function is found\iref{over.match.viable}, overload resolution is performed again on a function call created by passing just @@ -6965,16 +7369,29 @@ \pnum When a coroutine is invoked, -after initializing its parameters\iref{expr.call}, -a copy is created for each coroutine parameter. -For a parameter of type \cv{}~\tcode{T}, -the copy is a variable of type \cv{}~\tcode{T} +a copy is created for each coroutine parameter +at the beginning of the replacement body. +For a parameter +whose original declaration specified the type \cv{}~\tcode{T}, +\begin{itemize} +\item +if \tcode{T} is a reference type, +the copy is a reference of type +\cv{}~\tcode{T} +bound to the same object as a parameter; +\item +otherwise, the copy is a variable +of type \cv{}~\tcode{T} with automatic storage duration that is direct-initialized from an xvalue of type \tcode{T} referring to the parameter. +\end{itemize} \begin{note} -An original parameter object is never -a const or volatile object\iref{basic.type.qualifier}. +An identifier in the \grammarterm{function-body} +that names one of these parameters +refers to the created copy, +not the original parameter\iref{expr.prim.id.unqual}. \end{note} + The initialization and destruction of each parameter copy occurs in the context of the called coroutine. Initializations of parameter copies are sequenced before the call to the @@ -6998,23 +7415,68 @@ The expression \keyword{co_await} \tcode{\exposid{promise}.final_suspend()} shall not be potentially-throwing\iref{except.spec}. +\rSec2[dcl.fct.def.replace]{Replaceable function definitions} + +\pnum +Certain functions +for which a definition is supplied by the implementation +are \defn{replaceable}. +A \Cpp{} program may +provide a definition with the signature of a replaceable function, +called a \defnadj{replacement}{function}. +The replacement function +is used instead of the default version +supplied by the implementation. +Such replacement occurs +prior to program startup\iref{basic.def.odr,basic.start}. +A declaration of the replacement function +\begin{itemize} +\item +shall not be inline, +\item +shall be attached to the global module, +\item +shall have \Cpp{} language linkage, +\item +shall have the same return type as the replaceable function, and +\item +if the function is declared in a standard library header, +shall be such that it would be valid as a redeclaration +of the declaration in that header; +\end{itemize} +no diagnostic is required. +\begin{note} +The one-definition rule\iref{basic.def.odr}) +applies to the definitions of a replaceable function +provided by the program. +The implementation-supplied function definition +is an otherwise-unnamed function with no linkage. +\end{note} + + \rSec1[dcl.struct.bind]{Structured binding declarations}% \indextext{structured binding declaration}% \indextext{declaration!structured binding|see{structured binding declaration}}% \pnum A structured binding declaration introduces the \grammarterm{identifier}{s} -$\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc$ +$\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc, \tcode{v}_{N-1}$ of the -\grammarterm{attributed-identifier-list} as names -of \defn{structured binding}{s}. +\grammarterm{sb-identifier-list} as names. +An \grammarterm{sb-identifier} that contains an ellipsis +introduces a structured binding pack\iref{temp.variadic}. +A \defn{structured binding} is either +an \grammarterm{sb-identifier} that does not contain an ellipsis or +an element of a structured binding pack. The optional \grammarterm{attribute-specifier-seq} of -an \grammarterm{attributed-identifier} -appertains to the structured binding so introduced. +an \grammarterm{sb-identifier} +appertains to the associated structured bindings. Let \cv{} denote the \grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq} and -\placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of -the \grammarterm{decl-specifier-seq} (if any). +\placeholder{S} consist of +each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} +that is \tcode{constexpr}, \tcode{constinit}, or +a \grammarterm{storage-class-specifier}. A \cv{} that includes \tcode{volatile} is deprecated; see~\ref{depr.volatile.type}. First, a variable with a unique name \exposid{e} is introduced. If the @@ -7042,15 +7504,56 @@ \tcode{E} is never a reference type\iref{expr.prop}. \end{note} +\pnum +The \defn{structured binding size} of \tcode{E}, as defined below, +is the number of structured bindings +that need to be introduced by the structured binding declaration. +If there is no structured binding pack, +then the number of elements in the \grammarterm{sb-identifier-list} +shall be equal to the structured binding size of \tcode{E}. +Otherwise, the number of non-pack elements shall be no more than +the structured binding size of \tcode{E}; +the number of elements of the structured binding pack is +the structured binding size of \tcode{E} less +the number of non-pack elements in the\grammarterm{sb-identifier-list}. + +\pnum +Let $\textrm{SB}_i$ denote +the $i^\textrm{th}$ structured binding in the structured binding declaration +after expanding the structured binding pack, if any. +\begin{note} +If there is no structured binding pack, +then $\textrm{SB}_i$ denotes $\tcode{v}_i$. +\end{note} +\begin{example} +\begin{codeblock} +struct C { int x, y, z; }; + +template +void now_i_know_my() { + auto [a, b, c] = C(); // OK, $\textrm{SB}_0$ is \tcode{a}, $\textrm{SB}_1$ is \tcode{b}, and $\textrm{SB}_2$ is \tcode{c} + auto [d, ...e] = C(); // OK, $\textrm{SB}_0$ is \tcode{d}, the pack \tcode{e} $(\tcode{v}_1)$ contains two structured bindings: $\textrm{SB}_1$ and $\textrm{SB}_2$ + auto [...f, g] = C(); // OK, the pack \tcode{f} $(\tcode{v}_0)$ contains two structured bindings: $\textrm{SB}_0$ and $\textrm{SB}_1$, and $\textrm{SB}_2$ is \tcode{g} + auto [h, i, j, ...k] = C(); // OK, the pack \tcode{k} is empty + auto [l, m, n, o, ...p] = C(); // error: structured binding size is too small +} +\end{codeblock} +\end{example} + +\pnum +If a structured binding declaration appears as a \grammarterm{condition}, +the decision variable\iref{stmt.pre} of the condition is \exposid{e}. + \pnum If the \grammarterm{initializer} refers to one of the names introduced by the structured binding declaration, the program is ill-formed. \pnum -If \tcode{E} is an array type with element type \tcode{T}, the number -of elements in the \grammarterm{attributed-identifier-list} shall be equal to the -number of elements of \tcode{E}. Each $\tcode{v}_i$ is the name of an +If \tcode{E} is an array type with element type \tcode{T}, +the structured binding size of \tcode{E} is equal to the +number of elements of \tcode{E}. +Each $\textrm{SB}_i$ is the name of an lvalue that refers to the element $i$ of the array and whose type is \tcode{T}; the referenced type is \tcode{T}. \begin{note} @@ -7061,6 +7564,19 @@ auto f() -> int(&)[2]; auto [ x, y ] = f(); // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value auto& [ xr, yr ] = f(); // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value + +auto g() -> int(&)[4]; + +template +void h(int (&arr)[N]) { + auto [a, ...b, c] = arr; // \tcode{a} names the first element of the array, \tcode{b} is a pack referring to the second and + // third elements, and \tcode{c} names the fourth element + auto& [...e] = arr; // \tcode{e} is a pack referring to the four elements of the array +} + +void call_h() { + h(g()); +} \end{codeblock} \end{example} @@ -7071,8 +7587,7 @@ the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression and -the number of elements in -the \grammarterm{attributed-identifier-list} shall be equal to the value of that +the structured binding size of \tcode{E} is equal to the value of that expression. Let \tcode{i} be an index prvalue of type \tcode{std::size_t} corresponding to $\tcode{v}_i$. @@ -7080,7 +7595,7 @@ in the scope of \tcode{E}\iref{class.member.lookup} finds at least one declaration that is a function template whose first template parameter -is a non-type parameter, +is a constant template parameter, the initializer is \tcode{\exposidnc{e}.get()}. Otherwise, the initializer is \tcode{get(\exposid{e})}, where \tcode{get} undergoes argument-dependent lookup\iref{basic.lookup.argdep}. @@ -7102,9 +7617,15 @@ \placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;} \end{ncbnf} -Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ +Each $\textrm{SB}_i$ is the name of an lvalue of type $\tcode{T}_i$ that refers to the object bound to $\tcode{r}_i$; the referenced type is $\tcode{T}_i$. +The initialization of \exposid{e} and +any conversion of \exposid{e} considered as a decision variable\iref{stmt.pre} +is +sequenced before the initialization of any $\tcode{r}_i$. +The initialization of each $\tcode{r}_i$ is +sequenced before the initialization of any $\tcode{r}_j$ where $i < j$. \pnum Otherwise, @@ -7114,12 +7635,12 @@ well-formed when named as \tcode{\exposidnc{e}.\placeholder{name}} in the context of the structured binding, \tcode{E} shall not have an anonymous union member, and -the number of elements in the \grammarterm{attributed-identifier-list} shall be +the structured binding size of \tcode{E} is equal to the number of non-static data members of \tcode{E}. Designating the non-static data members of \tcode{E} as $\tcode{m}_0$, $\tcode{m}_1$, $\tcode{m}_2, \dotsc$ (in declaration order), -each $\tcode{v}_i$ is the +each $\textrm{SB}_i$ is the name of an lvalue that refers to the member \tcode{m}$_i$ of \exposid{e} and whose type is that of \tcode{\exposidnc{e}.$\tcode{m}_i$}\iref{expr.ref}; @@ -7477,11 +7998,26 @@ \pnum A \grammarterm{using-enum-declarator} names the set of declarations found by -lookup\iref{basic.lookup.unqual,basic.lookup.qual} -for the \grammarterm{using-enum-declarator}. +type-only lookup\iref{basic.lookup.general} +for the \grammarterm{using-enum-declarator}\iref{basic.lookup.unqual,basic.lookup.qual}. The \grammarterm{using-enum-declarator} shall designate a non-dependent type with a reachable \grammarterm{enum-specifier}. +\begin{example} +\begin{codeblock} +enum E { x }; +void f() { + int E; + using enum E; // OK +} +using F = E; +using enum F; // OK +template using EE = T; +void g() { + using enum EE; // OK +} +\end{codeblock} +\end{example} \pnum A \grammarterm{using-enum-declaration} @@ -8659,8 +9195,8 @@ \pnum \indextext{object!linkage specification}% \indextext{linkage!implementation-defined object}% -Linkage from \Cpp{} to objects defined in other languages and to objects -defined in \Cpp{} from other languages is \impldef{linkage of objects between \Cpp{} and other languages} and +Linkage from \Cpp{} to entities defined in other languages and to entities +defined in \Cpp{} from other languages is \impldef{linkage of entities between \Cpp{} and other languages} and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.% @@ -8674,11 +9210,11 @@ \pnum \indextext{attribute!syntax and semantics}% Attributes specify additional information for various source constructs -such as types, variables, names, blocks, or translation units. +such as types, variables, names, contract assertions, blocks, or translation units. \begin{bnf} \nontermdef{attribute-specifier-seq}\br - \opt{attribute-specifier-seq} attribute-specifier + attribute-specifier \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} @@ -8734,12 +9270,11 @@ \begin{bnf} \nontermdef{balanced-token-seq}\br - balanced-token\br - balanced-token-seq balanced-token + balanced-token \opt{balanced-token-seq} \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{balanced-token}\br \terminal{(} \opt{balanced-token-seq} \terminal{)}\br \terminal{[} \opt{balanced-token-seq} \terminal{]}\br @@ -8798,7 +9333,7 @@ \pnum Each \grammarterm{attribute-specifier-seq} is said to \defn{appertain} to some entity or statement, identified by the syntactic context -where it appears\iref{stmt.stmt,dcl.dcl,dcl.decl}. +where it appears\iref{stmt,dcl,dcl.decl}. If an \grammarterm{attribute-specifier-seq} that appertains to some entity or statement contains an \grammarterm{attribute} or \grammarterm{alignment-specifier} that is not allowed to apply to that @@ -8969,6 +9504,7 @@ \rSec2[dcl.attr.assume]{Assumption attribute} +\pnum The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement; such a statement is an \defn{assumption}. An \grammarterm{attribute-argument-clause} shall be present and @@ -8981,7 +9517,10 @@ If the converted expression would evaluate to \tcode{true} at the point where the assumption appears, the assumption has no effect. -Otherwise, the behavior is undefined. +Otherwise, +evaluation of the assumption has runtime-undefined behavior. + +\pnum \begin{note} The expression is potentially evaluated\iref{basic.def.odr}. The use of assumptions is intended to allow implementations @@ -8995,6 +9534,8 @@ if an implementation does not attempt to deduce any such information from assumptions. \end{note} + +\pnum \begin{example} \begin{codeblock} int divide_by_32(int x) { @@ -9009,86 +9550,6 @@ \end{codeblock} \end{example} -\rSec2[dcl.attr.depend]{Carries dependency attribute}% -\indextext{attribute!carries dependency} - -\pnum -The \grammarterm{attribute-token} \tcode{carries_dependency} specifies -dependency propagation into and out of functions. -No -\grammarterm{attribute-argument-clause} shall be present. The attribute may be -applied to a parameter of a function or lambda, in -which case it specifies that the initialization of the parameter carries a -dependency to\iref{intro.multithread} each lvalue-to-rvalue -conversion\iref{conv.lval} of that object. The attribute may also be applied -to a function or a lambda call operator, in which case it -specifies that the return value, if any, carries a dependency to the evaluation -of the function call expression. - -\pnum -The first declaration of a function shall specify the \tcode{carries_dependency} attribute for its -\grammarterm{declarator-id} if any declaration of the function specifies the -\tcode{carries_dependency} attribute. Furthermore, the first declaration of a function shall specify -the \tcode{carries_dependency} attribute for a parameter if any declaration of that function -specifies the \tcode{carries_dependency} attribute for that parameter. If a function or one of its -parameters is declared with the \tcode{carries_dependency} attribute in its first declaration in one -translation unit and the same function or one of its parameters is declared without the -\tcode{carries_dependency} attribute in its first declaration in another translation unit, the -program is ill-formed, no diagnostic required. - -\pnum -\begin{note} -The \tcode{carries_dependency} attribute does not change the meaning of the -program, but might result in generation of more efficient code. -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -/* Translation unit A. */ - -struct foo { int* a; int* b; }; -std::atomic foo_head[10]; -int foo_array[10][10]; - -[[carries_dependency]] struct foo* f(int i) { - return foo_head[i].load(memory_order::consume); -} - -int g(int* x, int* y [[carries_dependency]]) { - return kill_dependency(foo_array[*x][*y]); -} - -/* Translation unit B. */ - -[[carries_dependency]] struct foo* f(int i); -int g(int* x, int* y [[carries_dependency]]); - -int c = 3; - -void h(int i) { - struct foo* p; - - p = f(i); - do_something_with(g(&c, p->a)); - do_something_with(g(p->a, &c)); -} -\end{codeblock} - -The \tcode{carries_dependency} attribute on function \tcode{f} means that the -return value carries a dependency out of \tcode{f}, so that the implementation -need not constrain ordering upon return from \tcode{f}. Implementations of -\tcode{f} and its caller may choose to preserve dependencies instead of emitting -hardware memory ordering instructions (a.k.a.\ fences). -Function \tcode{g}'s second parameter has a \tcode{carries_dependency} attribute, -but its first parameter does not. Therefore, function \tcode{h}'s first call to -\tcode{g} carries a dependency into \tcode{g}, but its second call does not. The -implementation might need to insert a fence prior to the second call to -\tcode{g}. -\end{example} -\indextext{attribute|)}% -\indextext{declaration|)} - \rSec2[dcl.attr.deprecated]{Deprecated attribute}% \indextext{attribute!deprecated} @@ -9334,6 +9795,7 @@ \grammarterm{typedef-name}, variable (including a structured binding declaration), structured binding, +result binding\iref{dcl.contract.res}, non-static data member, function, enumeration, or @@ -9432,6 +9894,7 @@ \recommended Appearance of a nodiscard call as a potentially-evaluated discarded-value expression\iref{expr.prop} +of non-void type is discouraged unless explicitly cast to \keyword{void}. Implementations should issue a warning in such cases. The value of @@ -9488,8 +9951,9 @@ translation unit, the program is ill-formed, no diagnostic required. \pnum -If a function \tcode{f} is called where \tcode{f} was previously declared with the \tcode{noreturn} -attribute and \tcode{f} eventually returns, the behavior is undefined. +If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn} +attribute and that invocation eventually returns, +the behavior is runtime-undefined. \begin{note} The function can terminate by throwing an exception. @@ -9562,3 +10026,6 @@ could have the same address as \tcode{buckets} if their respective types are all empty. \end{example} + +\indextext{attribute|)}% +\indextext{declaration|)} diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 1b4ce24a75..1f5f1ad48a 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} @@ -81,8 +82,8 @@ namespace std { class logic_error : public exception { public: - explicit logic_error(const string& what_arg); - explicit logic_error(const char* what_arg); + constexpr explicit logic_error(const string& what_arg); + constexpr explicit logic_error(const char* what_arg); }; } \end{codeblock} @@ -97,7 +98,7 @@ \indexlibraryctor{logic_error}% \begin{itemdecl} -logic_error(const string& what_arg); +constexpr logic_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -108,7 +109,7 @@ \indexlibraryctor{logic_error}% \begin{itemdecl} -logic_error(const char* what_arg); +constexpr logic_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -124,8 +125,8 @@ namespace std { class domain_error : public logic_error { public: - explicit domain_error(const string& what_arg); - explicit domain_error(const char* what_arg); + constexpr explicit domain_error(const string& what_arg); + constexpr explicit domain_error(const char* what_arg); }; } \end{codeblock} @@ -138,7 +139,7 @@ \indexlibraryctor{domain_error}% \begin{itemdecl} -domain_error(const string& what_arg); +constexpr domain_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -149,7 +150,7 @@ \indexlibraryctor{domain_error}% \begin{itemdecl} -domain_error(const char* what_arg); +constexpr domain_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -165,8 +166,8 @@ namespace std { class invalid_argument : public logic_error { public: - explicit invalid_argument(const string& what_arg); - explicit invalid_argument(const char* what_arg); + constexpr explicit invalid_argument(const string& what_arg); + constexpr explicit invalid_argument(const char* what_arg); }; } \end{codeblock} @@ -178,7 +179,7 @@ \indexlibraryctor{invalid_argument}% \begin{itemdecl} -invalid_argument(const string& what_arg); +constexpr invalid_argument(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -189,7 +190,7 @@ \indexlibraryctor{invalid_argument}% \begin{itemdecl} -invalid_argument(const char* what_arg); +constexpr invalid_argument(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -205,8 +206,8 @@ namespace std { class length_error : public logic_error { public: - explicit length_error(const string& what_arg); - explicit length_error(const char* what_arg); + constexpr explicit length_error(const string& what_arg); + constexpr explicit length_error(const char* what_arg); }; } \end{codeblock} @@ -220,7 +221,7 @@ \indexlibraryctor{length_error}% \begin{itemdecl} -length_error(const string& what_arg); +constexpr length_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -231,7 +232,7 @@ \indexlibraryctor{length_error}% \begin{itemdecl} -length_error(const char* what_arg); +constexpr length_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -247,8 +248,8 @@ namespace std { class out_of_range : public logic_error { public: - explicit out_of_range(const string& what_arg); - explicit out_of_range(const char* what_arg); + constexpr explicit out_of_range(const string& what_arg); + constexpr explicit out_of_range(const char* what_arg); }; } \end{codeblock} @@ -262,7 +263,7 @@ \indexlibraryctor{out_of_range}% \begin{itemdecl} -out_of_range(const string& what_arg); +constexpr out_of_range(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -273,7 +274,7 @@ \indexlibraryctor{out_of_range}% \begin{itemdecl} -out_of_range(const char* what_arg); +constexpr out_of_range(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -289,8 +290,8 @@ namespace std { class runtime_error : public exception { public: - explicit runtime_error(const string& what_arg); - explicit runtime_error(const char* what_arg); + constexpr explicit runtime_error(const string& what_arg); + constexpr explicit runtime_error(const char* what_arg); }; } \end{codeblock} @@ -303,7 +304,7 @@ \indexlibraryctor{runtime_error}% \begin{itemdecl} -runtime_error(const string& what_arg); +constexpr runtime_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -314,7 +315,7 @@ \indexlibraryctor{runtime_error}% \begin{itemdecl} -runtime_error(const char* what_arg); +constexpr runtime_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -330,8 +331,8 @@ namespace std { class range_error : public runtime_error { public: - explicit range_error(const string& what_arg); - explicit range_error(const char* what_arg); + constexpr explicit range_error(const string& what_arg); + constexpr explicit range_error(const char* what_arg); }; } \end{codeblock} @@ -344,7 +345,7 @@ \indexlibraryctor{range_error}% \begin{itemdecl} -range_error(const string& what_arg); +constexpr range_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -355,7 +356,7 @@ \indexlibraryctor{range_error}% \begin{itemdecl} -range_error(const char* what_arg); +constexpr range_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -371,8 +372,8 @@ namespace std { class overflow_error : public runtime_error { public: - explicit overflow_error(const string& what_arg); - explicit overflow_error(const char* what_arg); + constexpr explicit overflow_error(const string& what_arg); + constexpr explicit overflow_error(const char* what_arg); }; } \end{codeblock} @@ -384,7 +385,7 @@ \indexlibraryctor{overflow_error}% \begin{itemdecl} -overflow_error(const string& what_arg); +constexpr overflow_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -395,7 +396,7 @@ \indexlibraryctor{overflow_error}% \begin{itemdecl} -overflow_error(const char* what_arg); +constexpr overflow_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -411,8 +412,8 @@ namespace std { class underflow_error : public runtime_error { public: - explicit underflow_error(const string& what_arg); - explicit underflow_error(const char* what_arg); + constexpr explicit underflow_error(const string& what_arg); + constexpr explicit underflow_error(const char* what_arg); }; } \end{codeblock} @@ -424,7 +425,7 @@ \indexlibraryctor{underflow_error}% \begin{itemdecl} -underflow_error(const string& what_arg); +constexpr underflow_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -435,7 +436,7 @@ \indexlibraryctor{underflow_error}% \begin{itemdecl} -underflow_error(const char* what_arg); +constexpr underflow_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -455,9 +456,8 @@ \rSec2[cassert.syn]{Header \tcode{} synopsis} -\indexlibraryglobal{assert}% \begin{codeblock} -#define assert(...) @\seebelow@ +#define @\libmacro{assert}@(...) @\seebelow@ \end{codeblock} \rSec2[assertions.assert]{The \tcode{assert} macro} @@ -467,11 +467,11 @@ at the point in the source file where \tcode{} is included, the \tcode{assert} macro is defined as \begin{codeblock} -#define assert(...) ((void)0) +#define @\libmacro{assert}@(...) ((void)0) \end{codeblock} \pnum -Otherwise, the \tcode{assert} macro puts a diagnostic test into programs; +Otherwise, the \libmacro{assert} macro puts a diagnostic test into programs; it expands to an expression of type \keyword{void} which has the following effects: @@ -521,7 +521,7 @@ \pnum The contents of the header \libheaderdef{cerrno} are the same as the POSIX header -\libheader{errno.h}, except that \tcode{errno} shall be defined as a macro. +\libheader{errno.h}, except that \libmacro{errno} shall be defined as a macro. \begin{note} The intent is to remain in close alignment with the POSIX standard. \end{note} @@ -529,158 +529,83 @@ \rSec2[cerrno.syn]{Header \tcode{} synopsis} -\indexlibraryglobal{errno}% -\indexlibraryglobal{E2BIG}% -\indexlibraryglobal{EACCES}% -\indexlibraryglobal{EADDRINUSE}% -\indexlibraryglobal{EADDRNOTAVAIL}% -\indexlibraryglobal{EAFNOSUPPORT}% -\indexlibraryglobal{EAGAIN}% -\indexlibraryglobal{EALREADY}% -\indexlibraryglobal{EBADF}% -\indexlibraryglobal{EBADMSG}% -\indexlibraryglobal{EBUSY}% -\indexlibraryglobal{ECANCELED}% -\indexlibraryglobal{ECHILD}% -\indexlibraryglobal{ECONNABORTED}% -\indexlibraryglobal{ECONNREFUSED}% -\indexlibraryglobal{ECONNRESET}% -\indexlibraryglobal{EDEADLK}% -\indexlibraryglobal{EDESTADDRREQ}% -\indexlibraryglobal{EDOM}% -\indexlibraryglobal{EEXIST}% -\indexlibraryglobal{EFAULT}% -\indexlibraryglobal{EFBIG}% -\indexlibraryglobal{EHOSTUNREACH}% -\indexlibraryglobal{EIDRM}% -\indexlibraryglobal{EILSEQ}% -\indexlibraryglobal{EINPROGRESS}% -\indexlibraryglobal{EINTR}% -\indexlibraryglobal{EINVAL}% -\indexlibraryglobal{EIO}% -\indexlibraryglobal{EISCONN}% -\indexlibraryglobal{EISDIR}% -\indexlibraryglobal{ELOOP}% -\indexlibraryglobal{EMFILE}% -\indexlibraryglobal{EMLINK}% -\indexlibraryglobal{EMSGSIZE}% -\indexlibraryglobal{ENAMETOOLONG}% -\indexlibraryglobal{ENETDOWN}% -\indexlibraryglobal{ENETRESET}% -\indexlibraryglobal{ENETUNREACH}% -\indexlibraryglobal{ENFILE}% -\indexlibraryglobal{ENOBUFS}% -\indexlibraryglobal{ENODEV}% -\indexlibraryglobal{ENOENT}% -\indexlibraryglobal{ENOEXEC}% -\indexlibraryglobal{ENOLCK}% -\indexlibraryglobal{ENOLINK}% -\indexlibraryglobal{ENOMEM}% -\indexlibraryglobal{ENOMSG}% -\indexlibraryglobal{ENOPROTOOPT}% -\indexlibraryglobal{ENOSPC}% -\indexlibraryglobal{ENOSYS}% -\indexlibraryglobal{ENOTCONN}% -\indexlibraryglobal{ENOTDIR}% -\indexlibraryglobal{ENOTEMPTY}% -\indexlibraryglobal{ENOTRECOVERABLE}% -\indexlibraryglobal{ENOTSOCK}% -\indexlibraryglobal{ENOTSUP}% -\indexlibraryglobal{ENOTTY}% -\indexlibraryglobal{ENXIO}% -\indexlibraryglobal{EOPNOTSUPP}% -\indexlibraryglobal{EOVERFLOW}% -\indexlibraryglobal{EOWNERDEAD}% -\indexlibraryglobal{EPERM}% -\indexlibraryglobal{EPIPE}% -\indexlibraryglobal{EPROTO}% -\indexlibraryglobal{EPROTONOSUPPORT}% -\indexlibraryglobal{EPROTOTYPE}% -\indexlibraryglobal{ERANGE}% -\indexlibraryglobal{EROFS}% -\indexlibraryglobal{ESPIPE}% -\indexlibraryglobal{ESRCH}% -\indexlibraryglobal{ETIMEDOUT}% -\indexlibraryglobal{ETXTBSY}% -\indexlibraryglobal{EWOULDBLOCK}% -\indexlibraryglobal{EXDEV}% \begin{codeblock} -#define errno @\seebelow@ - -#define E2BIG @\seebelow@ // freestanding -#define EACCES @\seebelow@ // freestanding -#define EADDRINUSE @\seebelow@ // freestanding -#define EADDRNOTAVAIL @\seebelow@ // freestanding -#define EAFNOSUPPORT @\seebelow@ // freestanding -#define EAGAIN @\seebelow@ // freestanding -#define EALREADY @\seebelow@ // freestanding -#define EBADF @\seebelow@ // freestanding -#define EBADMSG @\seebelow@ // freestanding -#define EBUSY @\seebelow@ // freestanding -#define ECANCELED @\seebelow@ // freestanding -#define ECHILD @\seebelow@ // freestanding -#define ECONNABORTED @\seebelow@ // freestanding -#define ECONNREFUSED @\seebelow@ // freestanding -#define ECONNRESET @\seebelow@ // freestanding -#define EDEADLK @\seebelow@ // freestanding -#define EDESTADDRREQ @\seebelow@ // freestanding -#define EDOM @\seebelow@ // freestanding -#define EEXIST @\seebelow@ // freestanding -#define EFAULT @\seebelow@ // freestanding -#define EFBIG @\seebelow@ // freestanding -#define EHOSTUNREACH @\seebelow@ // freestanding -#define EIDRM @\seebelow@ // freestanding -#define EILSEQ @\seebelow@ // freestanding -#define EINPROGRESS @\seebelow@ // freestanding -#define EINTR @\seebelow@ // freestanding -#define EINVAL @\seebelow@ // freestanding -#define EIO @\seebelow@ // freestanding -#define EISCONN @\seebelow@ // freestanding -#define EISDIR @\seebelow@ // freestanding -#define ELOOP @\seebelow@ // freestanding -#define EMFILE @\seebelow@ // freestanding -#define EMLINK @\seebelow@ // freestanding -#define EMSGSIZE @\seebelow@ // freestanding -#define ENAMETOOLONG @\seebelow@ // freestanding -#define ENETDOWN @\seebelow@ // freestanding -#define ENETRESET @\seebelow@ // freestanding -#define ENETUNREACH @\seebelow@ // freestanding -#define ENFILE @\seebelow@ // freestanding -#define ENOBUFS @\seebelow@ // freestanding -#define ENODEV @\seebelow@ // freestanding -#define ENOENT @\seebelow@ // freestanding -#define ENOEXEC @\seebelow@ // freestanding -#define ENOLCK @\seebelow@ // freestanding -#define ENOLINK @\seebelow@ // freestanding -#define ENOMEM @\seebelow@ // freestanding -#define ENOMSG @\seebelow@ // freestanding -#define ENOPROTOOPT @\seebelow@ // freestanding -#define ENOSPC @\seebelow@ // freestanding -#define ENOSYS @\seebelow@ // freestanding -#define ENOTCONN @\seebelow@ // freestanding -#define ENOTDIR @\seebelow@ // freestanding -#define ENOTEMPTY @\seebelow@ // freestanding -#define ENOTRECOVERABLE @\seebelow@ // freestanding -#define ENOTSOCK @\seebelow@ // freestanding -#define ENOTSUP @\seebelow@ // freestanding -#define ENOTTY @\seebelow@ // freestanding -#define ENXIO @\seebelow@ // freestanding -#define EOPNOTSUPP @\seebelow@ // freestanding -#define EOVERFLOW @\seebelow@ // freestanding -#define EOWNERDEAD @\seebelow@ // freestanding -#define EPERM @\seebelow@ // freestanding -#define EPIPE @\seebelow@ // freestanding -#define EPROTO @\seebelow@ // freestanding -#define EPROTONOSUPPORT @\seebelow@ // freestanding -#define EPROTOTYPE @\seebelow@ // freestanding -#define ERANGE @\seebelow@ // freestanding -#define EROFS @\seebelow@ // freestanding -#define ESPIPE @\seebelow@ // freestanding -#define ESRCH @\seebelow@ // freestanding -#define ETIMEDOUT @\seebelow@ // freestanding -#define ETXTBSY @\seebelow@ // freestanding -#define EWOULDBLOCK @\seebelow@ // freestanding -#define EXDEV @\seebelow@ // freestanding +#define @\libmacro{errno}@ @\seebelow@ + +#define @\libmacro{E2BIG}@ @\seebelow@ // freestanding +#define @\libmacro{EACCES}@ @\seebelow@ // freestanding +#define @\libmacro{EADDRINUSE}@ @\seebelow@ // freestanding +#define @\libmacro{EADDRNOTAVAIL}@ @\seebelow@ // freestanding +#define @\libmacro{EAFNOSUPPORT}@ @\seebelow@ // freestanding +#define @\libmacro{EAGAIN}@ @\seebelow@ // freestanding +#define @\libmacro{EALREADY}@ @\seebelow@ // freestanding +#define @\libmacro{EBADF}@ @\seebelow@ // freestanding +#define @\libmacro{EBADMSG}@ @\seebelow@ // freestanding +#define @\libmacro{EBUSY}@ @\seebelow@ // freestanding +#define @\libmacro{ECANCELED}@ @\seebelow@ // freestanding +#define @\libmacro{ECHILD}@ @\seebelow@ // freestanding +#define @\libmacro{ECONNABORTED}@ @\seebelow@ // freestanding +#define @\libmacro{ECONNREFUSED}@ @\seebelow@ // freestanding +#define @\libmacro{ECONNRESET}@ @\seebelow@ // freestanding +#define @\libmacro{EDEADLK}@ @\seebelow@ // freestanding +#define @\libmacro{EDESTADDRREQ}@ @\seebelow@ // freestanding +#define @\libmacro{EDOM}@ @\seebelow@ // freestanding +#define @\libmacro{EEXIST}@ @\seebelow@ // freestanding +#define @\libmacro{EFAULT}@ @\seebelow@ // freestanding +#define @\libmacro{EFBIG}@ @\seebelow@ // freestanding +#define @\libmacro{EHOSTUNREACH}@ @\seebelow@ // freestanding +#define @\libmacro{EIDRM}@ @\seebelow@ // freestanding +#define @\libmacro{EILSEQ}@ @\seebelow@ // freestanding +#define @\libmacro{EINPROGRESS}@ @\seebelow@ // freestanding +#define @\libmacro{EINTR}@ @\seebelow@ // freestanding +#define @\libmacro{EINVAL}@ @\seebelow@ // freestanding +#define @\libmacro{EIO}@ @\seebelow@ // freestanding +#define @\libmacro{EISCONN}@ @\seebelow@ // freestanding +#define @\libmacro{EISDIR}@ @\seebelow@ // freestanding +#define @\libmacro{ELOOP}@ @\seebelow@ // freestanding +#define @\libmacro{EMFILE}@ @\seebelow@ // freestanding +#define @\libmacro{EMLINK}@ @\seebelow@ // freestanding +#define @\libmacro{EMSGSIZE}@ @\seebelow@ // freestanding +#define @\libmacro{ENAMETOOLONG}@ @\seebelow@ // freestanding +#define @\libmacro{ENETDOWN}@ @\seebelow@ // freestanding +#define @\libmacro{ENETRESET}@ @\seebelow@ // freestanding +#define @\libmacro{ENETUNREACH}@ @\seebelow@ // freestanding +#define @\libmacro{ENFILE}@ @\seebelow@ // freestanding +#define @\libmacro{ENOBUFS}@ @\seebelow@ // freestanding +#define @\libmacro{ENODEV}@ @\seebelow@ // freestanding +#define @\libmacro{ENOENT}@ @\seebelow@ // freestanding +#define @\libmacro{ENOEXEC}@ @\seebelow@ // freestanding +#define @\libmacro{ENOLCK}@ @\seebelow@ // freestanding +#define @\libmacro{ENOLINK}@ @\seebelow@ // freestanding +#define @\libmacro{ENOMEM}@ @\seebelow@ // freestanding +#define @\libmacro{ENOMSG}@ @\seebelow@ // freestanding +#define @\libmacro{ENOPROTOOPT}@ @\seebelow@ // freestanding +#define @\libmacro{ENOSPC}@ @\seebelow@ // freestanding +#define @\libmacro{ENOSYS}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTCONN}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTDIR}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTEMPTY}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTRECOVERABLE}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTSOCK}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTSUP}@ @\seebelow@ // freestanding +#define @\libmacro{ENOTTY}@ @\seebelow@ // freestanding +#define @\libmacro{ENXIO}@ @\seebelow@ // freestanding +#define @\libmacro{EOPNOTSUPP}@ @\seebelow@ // freestanding +#define @\libmacro{EOVERFLOW}@ @\seebelow@ // freestanding +#define @\libmacro{EOWNERDEAD}@ @\seebelow@ // freestanding +#define @\libmacro{EPERM}@ @\seebelow@ // freestanding +#define @\libmacro{EPIPE}@ @\seebelow@ // freestanding +#define @\libmacro{EPROTO}@ @\seebelow@ // freestanding +#define @\libmacro{EPROTONOSUPPORT}@ @\seebelow@ // freestanding +#define @\libmacro{EPROTOTYPE}@ @\seebelow@ // freestanding +#define @\libmacro{ERANGE}@ @\seebelow@ // freestanding +#define @\libmacro{EROFS}@ @\seebelow@ // freestanding +#define @\libmacro{ESPIPE}@ @\seebelow@ // freestanding +#define @\libmacro{ESRCH}@ @\seebelow@ // freestanding +#define @\libmacro{ETIMEDOUT}@ @\seebelow@ // freestanding +#define @\libmacro{ETXTBSY}@ @\seebelow@ // freestanding +#define @\libmacro{EWOULDBLOCK}@ @\seebelow@ // freestanding +#define @\libmacro{EXDEV}@ @\seebelow@ // freestanding \end{codeblock} \pnum @@ -712,9 +637,6 @@ \indexlibraryglobal{error_code}% \indexlibraryglobal{error_condition}% \indexlibraryglobal{system_error}% -\indexlibraryglobal{is_error_code_enum}% -\indexlibraryglobal{is_error_condition_enum}% -\indexlibraryglobal{errc}% \begin{codeblock} #include // see \ref{compare.syn} @@ -728,12 +650,12 @@ class system_error; template - struct is_error_code_enum : public false_type {}; + struct @\libglobal{is_error_code_enum}@ : public false_type {}; template - struct is_error_condition_enum : public false_type {}; + struct @\libglobal{is_error_condition_enum}@ : public false_type {}; - enum class errc { // freestanding + enum class @\libglobal{errc}@ { // freestanding address_family_not_supported, // \tcode{EAFNOSUPPORT} address_in_use, // \tcode{EADDRINUSE} address_not_available, // \tcode{EADDRNOTAVAIL} @@ -836,7 +758,7 @@ // \ref{syserr}, system error support template - constexpr bool is_error_code_enum_v = is_error_code_enum::value; + constexpr bool @\libglobal{is_error_code_enum_v}@ = is_error_code_enum::value; template constexpr bool is_error_condition_enum_v = is_error_condition_enum::value; } @@ -2009,7 +1931,7 @@ const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; @@ -2253,7 +2175,7 @@ \indexlibrarymember{empty}{basic_stacktrace}% \begin{itemdecl} -[[nodiscard]] bool empty() const noexcept; +bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -2485,3 +2407,99 @@ \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} +It is intended that, when invoked with a debugger present, the execution of the +program temporarily halts and execution is handed to the debugger until the +program is either terminated by the debugger or the debugger resumes execution +of the program as if the function was not invoked. In particular, there is no +intent for a call to this function to accomodate resumption of the program in a +different manner. If there is no debugger present, execution of the program can +end abnormally. +\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 +\required +This function has no preconditions. + +\pnum +\default +\impldef{default semantics of \tcode{is_debugger_present}}. + +\begin{note} +It is intended that, using an immediate (uncached) query to determine if the +program is being traced by a debugger, an implementation returns \tcode{true} +only when tracing the execution of the program with a debugger. On Windows or +equivalent systems, this can be achieved by calling the +\tcode{::IsDebuggerPresent()} Win32 function. For systems compatible with +ISO/IEC 23360:2021, this can be achieved by checking for a tracing process, with +a best-effort determination that such a tracing process is a debugger. +\end{note} + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. + +\end{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index 22fc97a325..79684e4c51 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -264,7 +264,7 @@ an incomplete type\iref{basic.types.general}, an abstract class type\iref{class.abstract}, or a pointer to an incomplete type other than -\cv{}~\keyword{void}\iref{basic.compound} +\cv{}~\keyword{void}\iref{basic.compound}, the program is ill-formed. \pnum @@ -317,6 +317,26 @@ the selected constructor is odr-used\iref{basic.def.odr} and the destructor of \tcode{T} is potentially invoked\iref{class.dtor}. +\pnum +\indextext{exception handling!uncaught}% +An exception is considered \defnx{uncaught}{uncaught exception} +after completing the initialization of the exception object +until completing the activation of a handler for the exception\iref{except.handle}. +\begin{note} +As a consequence, an exception is considered uncaught +during any stack unwinding resulting from it being thrown. +\end{note} + +\pnum +\indexlibraryglobal{uncaught_exceptions}% +If an exception is rethrown\iref{expr.throw,propagation}, +it is considered uncaught from the point of rethrow +until the rethrown exception is caught. +\begin{note} +The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} +returns the number of uncaught exceptions in the current thread. +\end{note} + \pnum \indextext{exception handling!rethrow}% \indextext{rethrow|see{exception handling, rethrow}}% @@ -331,7 +351,7 @@ \indextext{exception handling!terminate called@\tcode{terminate} called}% \indextext{\idxcode{terminate}!called}% If the exception handling mechanism -handling an uncaught exception\iref{except.uncaught} +handling an uncaught exception directly invokes a function that exits via an exception, the function \tcode{std::terminate} is invoked\iref{except.terminate}. \begin{example} @@ -359,7 +379,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 +624,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 +635,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 +exits the function body 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 +686,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 @@ -728,7 +771,7 @@ \begin{bnf} \nontermdef{noexcept-specifier}\br \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br - \keyword{noexcept}\br + \keyword{noexcept} \end{bnf} \pnum @@ -807,33 +850,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 @@ -850,7 +866,7 @@ (such as an overloaded operator, an allocation function in a \grammarterm{new-expression}, a constructor for a function argument, -or a destructor if $E$ is a full-expression\iref{intro.execution}) +or a destructor) that has a potentially-throwing exception specification, or \item @@ -971,9 +987,7 @@ \item in an expression, the function is selected by overload resolution\iref{over.match,over.over}; -\item the function is odr-used\iref{term.odr.use} or, if it appears in an -unevaluated operand, would be odr-used if the expression were -potentially-evaluated; +\item the function is odr-used\iref{term.odr.use}; \item the exception specification is compared to that of another declaration (e.g., an explicit specialization or an overriding virtual @@ -993,9 +1007,9 @@ \end{itemize} The exception specification of a defaulted function is evaluated as described above only when needed; similarly, the -\grammarterm{noexcept-specifier} of a specialization of a function -template or member function of a class template is instantiated only when -needed. +\grammarterm{noexcept-specifier} of a specialization +of a templated function +is instantiated only when needed. % \indextext{exception specification|)} @@ -1007,8 +1021,10 @@ The function \tcode{std::terminate}\iref{except.terminate} is used by the exception handling mechanism for coping with errors related to the exception handling -mechanism itself. The function -\tcode{std::current_exception()}\iref{propagation} and the class +mechanism itself. +The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} +reports how many exceptions are uncaught in the current thread. +The function \tcode{std::current_exception}\iref{propagation} and the class \tcode{std::nested_exception}\iref{except.nested} can be used by a program to capture the currently handled exception. @@ -1016,9 +1032,10 @@ \pnum \indextext{\idxcode{terminate}}% -% FIXME: What does it mean to abandon exception handling? -In some situations, exception handling is abandoned -for less subtle error handling techniques. +Some errors in a program cannot be recovered from, such as when an exception +is not handled or a \tcode{std::thread} object is destroyed while its thread +function is still executing. In such cases, +the function \tcode{std::terminate}\iref{exception.terminate} is invoked. \begin{note} These situations are: \indextext{\idxcode{terminate}!called}% @@ -1034,9 +1051,14 @@ \item% when the exception handling mechanism cannot find a handler for a thrown exception\iref{except.handle}, or -\item when the search for a handler\iref{except.handle} encounters the -outermost block of a function -with a non-throwing exception specification\iref{except.spec}, or +\item when the search for a handler\iref{except.handle} +exits the function body of a function +with a non-throwing exception specification\iref{except.spec}, +including when a contract-violation handler +invoked from an evaluation of +a function contract assertion\iref{basic.contract.eval} associated with the function +exits via an exception, +or \item% when the destruction of an object during stack unwinding\iref{except.ctor} @@ -1084,7 +1106,27 @@ \item% when a call to a \tcode{wait()}, \tcode{wait_until()}, or \tcode{wait_for()} function on a condition variable\iref{thread.condition.condvar,thread.condition.condvarany} -fails to meet a postcondition. +fails to meet a postcondition, or + +\item% +when a callback invocation exits via an exception +when requesting stop on +a \tcode{std::stop_source} or +a \tcode{std::in\-place_stop_source}\iref{stopsource.mem,stopsource.inplace.mem}, +or in the constructor of +\tcode{std::stop_callback} or +\tcode{std::inplace_stop_callback}\iref{stopcallback.cons,stopcallback.inplace.cons} +when a callback invocation exits via an exception, or + +\item% +when a \tcode{run_loop} object is destroyed +that is still in the \tcode{running} state\iref{exec.run.loop}, or + +\item% +when \tcode{unhandled_stopped} is called on +a \tcode{with_awaitable_senders} object\iref{exec.with.awaitable.senders} +whose continuation is not a handle to a coroutine +whose promise type has an \tcode{unhandled_stopped} member function. \end{itemize} @@ -1092,14 +1134,12 @@ \pnum \indextext{\idxcode{terminate}}% -In such cases, -the function \tcode{std::terminate} is invoked\iref{exception.terminate}. In the situation where no matching handler is found, it is \impldef{stack unwinding before invocation of \tcode{std::terminate}} whether or not the stack is unwound before \tcode{std::terminate} is invoked. -In the situation where the search for a handler\iref{except.handle} encounters the -outermost block of a function +In the situation where the search for a handler\iref{except.handle} +exits the function body of a function with a non-throwing exception specification\iref{except.spec}, it is \impldef{whether stack is unwound before invoking the function \tcode{std::terminate} when a \tcode{noexcept} specification is violated} @@ -1112,21 +1152,4 @@ prematurely based on a determination that the unwind process will eventually cause an invocation of the function \tcode{std::terminate}. - -\rSec2[except.uncaught]{The \tcode{std::uncaught_exceptions} function}% -\indexlibraryglobal{uncaught_exceptions} - -\pnum -An exception is considered uncaught -after completing the initialization of the exception object\iref{except.throw} -until completing the activation of a handler for the exception\iref{except.handle}. -\begin{note} -As a consequence, an exception is considered uncaught -during any stack unwinding resulting from it being thrown. -\end{note} -If an exception is rethrown\iref{expr.throw,propagation}, -it is considered uncaught from the point of rethrow -until the rethrown exception is caught. -The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions} -returns the number of uncaught exceptions in the current thread.% \indextext{exception handling|)} diff --git a/source/exec.tex b/source/exec.tex new file mode 100644 index 0000000000..a26e23fc4c --- /dev/null +++ b/source/exec.tex @@ -0,0 +1,5675 @@ +%!TEX root = std.tex +\rSec0[exec]{Execution control library} + +\rSec1[exec.general]{General} + +\pnum +This Clause describes components +supporting execution of function objects\iref{function.objects}. + +\pnum +The following subclauses describe +the requirements, concepts, and components +for execution control primitives as summarized in \tref{exec.summary}. + +\begin{libsumtab}{Execution control library summary}{exec.summary} +\ref{exec.sched} & Schedulers & \tcode{} \\ +\ref{exec.recv} & Receivers & \\ +\ref{exec.opstate} & Operation states & \\ +\ref{exec.snd} & Senders & \\ +\end{libsumtab} + +\pnum +\tref{exec.pos} shows +the types of customization point objects\iref{customization.point.object} +used in the execution control library. + +\begin{floattable}{Types of customization point objects in the execution control library}{exec.pos}{lx{0.23\hsize}x{0.45\hsize}} +\topline +\lhdr{Customization point} & \chdr{Purpose} & \rhdr{Examples} \\ +\lhdr{object type} & & \\ +\capsep +core & + provide core execution functionality, and connection between core components & + e.g., \tcode{connect}, \tcode{start} \\ +completion functions & + called by senders to announce the completion of the work (success, error, or cancellation) & + \tcode{set_value}, \tcode{set_error}, \tcode{set_stopped} \\ +senders & + allow the specialization of the provided sender algorithms & + \begin{itemize} + \item sender factories (e.g., \tcode{schedule}, \tcode{just}, \tcode{read_env}) + \item sender adaptors (e.g., \tcode{continues_on}, \tcode{then}, \tcode{let_value}) + \item sender consumers (e.g., \tcode{sync_wait}) + \end{itemize} + \\ +queries & + allow querying different properties of objects & + \begin{itemize} + \item general queries (e.g., \tcode{get_allocator}, \tcode{get_stop_token}) + \item environment queries (e.g., \tcode{get_scheduler}, \tcode{get_delegation_scheduler}) + \item scheduler queries (e.g., \tcode{get_forward_progress_guarantee}) + \item sender attribute queries (e.g., \tcode{get_completion_scheduler}) + \end{itemize} + \\ +\end{floattable} + +\pnum +This clause makes use of the following exposition-only entities. + +\pnum +For a subexpression \tcode{expr}, +let \tcode{\exposid{MANDATE-NOTHROW}(expr)} be +expression-equivalent to \tcode{expr}. + +\mandates +\tcode{noexcept(expr)} is \tcode{true}. + +\pnum +\begin{codeblock} +namespace std { + template + concept @\defexposconcept{movable-value}@ = // \expos + @\libconcept{move_constructible}@> && + @\libconcept{constructible_from}@, T> && + (!is_array_v>); +} +\end{codeblock} + +\pnum +For function types \tcode{F1} and \tcode{F2} denoting +\tcode{R1(Args1...)} and \tcode{R2(Args2...)}, respectively, +\tcode{\exposid{MATCHING-SIG}(F1, F2)} is \tcode{true} if and only if +\tcode{\libconcept{same_as}} +is \tcode{true}. + +\pnum +For a subexpression \tcode{err}, +let \tcode{Err} be \tcode{decltype((err))} and +let \tcode{\exposid{AS-EXCEPT-PTR}(err)} be: +\begin{itemize} +\item +\tcode{err} if \tcode{decay_t} denotes the type \tcode{exception_ptr}. + +\expects +\tcode{!err} is \tcode{false}. +\item +Otherwise, +\tcode{make_exception_ptr(system_error(err))} +if \tcode{decay_t} denotes the type \tcode{error_code}. +\item +Otherwise, \tcode{make_exception_ptr(err)}. +\end{itemize} + +\pnum +For a subexpression \tcode{expr}, +let \tcode{\exposid{AS-CONST}(expr)} be expression-equivalent to +\begin{codeblock} +[](const auto& x) noexcept -> const auto& { return x; }(expr) +\end{codeblock} + +\rSec1[exec.queryable]{Queries and queryables} + +\rSec2[exec.queryable.general]{General} + +\pnum +A \defnadj{queryable}{object} is +a read-only collection of key/value pair +where each key is a customization point object known as a \defn{query object}. +A \defn{query} is an invocation of a query object +with a queryable object as its first argument and +a (possibly empty) set of additional arguments. +A query imposes syntactic and semantic requirements on its invocations. + +\pnum +Let \tcode{q} be a query object, +let \tcode{args} be a (possibly empty) pack of subexpressions, +let \tcode{env} be a subexpression +that refers to a queryable object \tcode{o} of type \tcode{O}, and +let \tcode{cenv} be a subexpression referring to \tcode{o} +such that \tcode{decltype((cenv))} is \tcode{const O\&}. +The expression \tcode{q(env, args...)} is equal to\iref{concepts.equality} +the expression \tcode{q(cenv, args...)}. + +\pnum +The type of a query expression cannot be \tcode{void}. + +\pnum +The expression \tcode{q(env, args...)} is +equality-preserving\iref{concepts.equality} and +does not modify the query object or the arguments. + +\pnum +If the expression \tcode{env.query(q, args...)} is well-formed, +then it is expression-equivalent to \tcode{q(env, args...)}. + +\pnum +Unless otherwise specified, +the result of a query is valid as long as the queryable object is valid. + +\rSec2[exec.queryable.concept]{\tcode{queryable} concept} + +\begin{codeblock} +namespace std { + template + concept @\defexposconcept{queryable}@ = @\libconcept{destructible}@; // \expos +} +\end{codeblock} + +\pnum +The exposition-only \exposconcept{queryable} concept specifies +the constraints on the types of queryable objects. + +\pnum +Let \tcode{env} be an object of type \tcode{Env}. +The type \tcode{Env} models \exposconcept{queryable} +if for each callable object \tcode{q} and a pack of subexpressions \tcode{args}, +if \tcode{requires \{ q(env, args...) \}} is \tcode{true} then +\tcode{q(env, args...)} meets any semantic requirements imposed by \tcode{q}. + +\rSec1[exec.async.ops]{Asynchronous operations} + +\pnum +An \defnadj{execution}{resource} is a program entity that manages +a (possibly dynamic) set of execution agents\iref{thread.req.lockable.general}, +which it uses to execute parallel work on behalf of callers. +\begin{example} +The currently active thread, +a system-provided thread pool, and +uses of an API associated with an external hardware accelerator +are all examples of execution resources. +\end{example} +Execution resources execute asynchronous operations. +An execution resource is either valid or invalid. + +\pnum +An \defnadj{asynchronous}{operation} is +a distinct unit of program execution that +\begin{itemize} +\item +is explicitly created; +\item +can be explicitly started once at most; +\item +once started, eventually completes exactly once +with a (possibly empty) set of result datums and +in exactly one of three \defnx{dispositions}{disposition}: +success, failure, or cancellation; +\begin{itemize} +\item +A successful completion, also known as a \defnadj{value}{completion}, +can have an arbitrary number of result datums. +\item +A failure completion, also known as an \defnadj{error}{completion}, +has a single result datum. +\item +A cancellation completion, also known as a \defnadj{stopped}{completion}, +has no result datum. +\end{itemize} +An asynchronous operation's \defnadj{async}{result} +is its disposition and its (possibly empty) set of result datums. +\item +can complete on a different execution resource +than the execution resource on which it started; and +\item +can create and start other asynchronous operations +called \defnadj{child}{operations}. +A child operation is an asynchronous operation +that is created by the parent operation and, +if started, completes before the parent operation completes. +A \defnadj{parent}{operation} is the asynchronous operation +that created a particular child operation. +\end{itemize} +\begin{note} +An asynchronous operation can execute synchronously; +that is, it can complete during the execution of its start operation +on the thread of execution that started it. +\end{note} + +\pnum +An asynchronous operation has associated state +known as its \defnadj{operation}{state}. + +\pnum +An asynchronous operation has an associated environment. +An \defn{environment} is a queryable object\iref{exec.queryable} +representing the execution-time properties of the operation's caller. +The caller of an asynchronous operation is +its parent operation or the function that created it. + +\pnum +An asynchronous operation has an associated receiver. +A \defn{receiver} is an aggregation of three handlers +for the three asynchronous completion dispositions: +\begin{itemize} +\item a value completion handler for a value completion, +\item an error completion handler for an error completion, and +\item a stopped completion handler for a stopped completion. +\end{itemize} +A receiver has an associated environment. +An asynchronous operation's operation state owns the operation's receiver. +The environment of an asynchronous operation +is equal to its receiver's environment. + +\pnum +For each completion disposition, there is a \defnadj{completion}{function}. +A completion function is +a customization point object\iref{customization.point.object} +that accepts an asynchronous operation's receiver as the first argument and +the result datums of the asynchronous operation as additional arguments. +The value completion function invokes +the receiver's value completion handler with the value result datums; +likewise for the error completion function and the stopped completion function. +A completion function has +an associated type known as its \defnadj{completion}{tag} +that is the unqualified type of the completion function. +A valid invocation of a completion function is called +a \defnadj{completion}{operation}. + +\pnum +The \defn{lifetime of an asynchronous operation}, +also known as the operation's \defn{async lifetime}, +begins when its start operation begins executing and +ends when its completion operation begins executing. +If the lifetime of an asynchronous operation's associated operation state +ends before the lifetime of the asynchronous operation, +the behavior is undefined. +After an asynchronous operation executes a completion operation, +its associated operation state is invalid. +Accessing any part of an invalid operation state is undefined behavior. + +\pnum +An asynchronous operation shall not execute a completion operation +before its start operation has begun executing. +After its start operation has begun executing, +exactly one completion operation shall execute. +The lifetime of an asynchronous operation's operation state can end +during the execution of the completion operation. + +\pnum +A \defn{sender} is a factory for one or more asynchronous operations. +\defnx{Connecting}{connect} a sender and a receiver creates +an asynchronous operation. +The asynchronous operation's associated receiver is equal to +the receiver used to create it, and +its associated environment is equal to +the environment associated with the receiver used to create it. +The lifetime of an asynchronous operation's associated operation state +does not depend on the lifetimes of either the sender or the receiver +from which it was created. +A sender is started when it is connected to a receiver and +the resulting asynchronous operation is started. +A sender's async result is the async result of the asynchronous operation +created by connecting it to a receiver. +A sender sends its results by way of the asynchronous operation(s) it produces, +and a receiver receives those results. +A sender is either valid or invalid; +it becomes invalid when its parent sender (see below) becomes invalid. + +\pnum +A \defn{scheduler} is an abstraction of an execution resource +with a uniform, generic interface for scheduling work onto that resource. +It is a factory for senders +whose asynchronous operations execute value completion operations +on an execution agent belonging to +the scheduler's associated execution resource. +A \defn{schedule-expression} obtains such a sender from a scheduler. +A \defn{schedule sender} is the result of a schedule expression. +On success, an asynchronous operation produced by a schedule sender executes +a value completion operation with an empty set of result datums. +Multiple schedulers can refer to the same execution resource. +A scheduler can be valid or invalid. +A scheduler becomes invalid when the execution resource to which it refers +becomes invalid, +as do any schedule senders obtained from the scheduler, and +any operation states obtained from those senders. + +\pnum +An asynchronous operation has one or more associated completion schedulers +for each of its possible dispositions. +A \defn{completion scheduler} is a scheduler +whose associated execution resource is used to execute +a completion operation for an asynchronous operation. +A value completion scheduler is a scheduler +on which an asynchronous operation's value completion operation can execute. +Likewise for error completion schedulers and stopped completion schedulers. + +\pnum +A sender has an associated queryable object\iref{exec.queryable} +known as its \defnx{attributes}{attribute} +that describes various characteristics of the sender and +of the asynchronous operation(s) it produces. +For each disposition, +there is a query object for reading the associated completion scheduler +from a sender's attributes; +i.e., a value completion scheduler query object +for reading a sender's value completion scheduler, etc. +If a completion scheduler query is well-formed, +the returned completion scheduler is unique +for that disposition for any asynchronous operation the sender creates. +A schedule sender is required to have a value completion scheduler attribute +whose value is equal to the scheduler that produced the schedule sender. + +\pnum +A \defn{completion signature} is a function type +that describes a completion operation. +An asynchronous operation has a finite set of possible completion signatures +corresponding to the completion operations +that the asynchronous operation potentially evaluates\iref{basic.def.odr}. +For a completion function \tcode{set}, +receiver \tcode{rcvr}, and +pack of arguments \tcode{args}, +let \tcode{c} be the completion operation \tcode{set(rcvr, args...)}, and +let \tcode{F} be +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 \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 +that has an environment of type \tcode{Env}. +The type of the receiver does not affect +an asynchronous operation's completion signatures, +only the type of the receiver's environment. + +\pnum +A sender algorithm is a function that takes and/or returns a sender. +There are three categories of sender algorithms: +\begin{itemize} +\item +A \defn{sender factory} is a function +that takes non-senders as arguments and that returns a sender. +\item +A \defn{sender adaptor} is a function +that constructs and returns a parent sender +from a set of one or more child senders and +a (possibly empty) set of additional arguments. +An asynchronous operation created by a parent sender is +a parent operation to the child operations created by the child senders. +\item +A \defn{sender consumer} is a function +that takes one or more senders and +a (possibly empty) set of additional arguments, and +whose return type is not the type of a sender. +\end{itemize} + +\rSec1[execution.syn]{Header \tcode{} synopsis} + +\indexheader{execution}% +\begin{codeblock} +namespace std { + // \ref{execpol.type}, execution policy type trait + template struct is_execution_policy; // freestanding + template constexpr bool @\libglobal{is_execution_policy_v}@ = // freestanding + is_execution_policy::value; +} + +namespace std::execution { + // \ref{execpol.seq}, sequenced execution policy + class sequenced_policy; + + // \ref{execpol.par}, parallel execution policy + class parallel_policy; + + // \ref{execpol.parunseq}, parallel and unsequenced execution policy + class parallel_unsequenced_policy; + + // \ref{execpol.unseq}, unsequenced execution policy + class unsequenced_policy; + + // \ref{execpol.objects}, execution policy objects + inline constexpr sequenced_policy seq{ @\unspec@ }; + inline constexpr parallel_policy par{ @\unspec@ }; + inline constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; + inline constexpr unsequenced_policy unseq{ @\unspec@ }; +} + +namespace std { + // \ref{exec.general}, helper concepts + template + concept @\exposconceptnc{movable-value}@ = @\seebelownc@; // \expos + + template + concept @\defexposconceptnc{decays-to}@ = @\libconcept{same_as}@, To>; // \expos + + template + concept @\defexposconceptnc{class-type}@ = @\exposconceptnc{decays-to}@ && is_class_v; // \expos + + // \ref{exec.queryable}, queryable objects + template + concept @\exposconceptnc{queryable}@ = @\seebelownc@; // \expos + + // \ref{exec.queries}, queries + struct @\libglobal{forwarding_query_t}@ { @\unspec@ }; + struct @\libglobal{get_allocator_t}@ { @\unspec@ }; + struct @\libglobal{get_stop_token_t}@ { @\unspec@ }; + + inline constexpr forwarding_query_t @\libglobal{forwarding_query}@{}; + inline constexpr get_allocator_t @\libglobal{get_allocator}@{}; + inline constexpr get_stop_token_t @\libglobal{get_stop_token}@{}; + + template + using stop_token_of_t = remove_cvref_t()))>; + + template + concept @\defexposconceptnc{forwarding-query}@ = forwarding_query(T{}); // \expos +} + +namespace std::execution { + // \ref{exec.queries}, queries + struct @\libglobal{get_domain_t}@ { @\unspec@ }; + struct @\libglobal{get_scheduler_t}@ { @\unspec@ }; + struct @\libglobal{get_delegation_scheduler_t}@ { @\unspec@ }; + struct @\libglobal{get_forward_progress_guarantee_t}@ { @\unspec@ }; + template + struct @\libglobal{get_completion_scheduler_t}@ { @\unspec@ }; + + inline constexpr get_domain_t @\libglobal{get_domain}@{}; + inline constexpr get_scheduler_t @\libglobal{get_scheduler}@{}; + inline constexpr get_delegation_scheduler_t @\libglobal{get_delegation_scheduler}@{}; + enum class forward_progress_guarantee; + inline constexpr get_forward_progress_guarantee_t @\libglobal{get_forward_progress_guarantee}@{}; + template + constexpr get_completion_scheduler_t @\libglobal{get_completion_scheduler}@{}; + + struct @\libglobal{get_env_t}@ { @\unspec@ }; + inline constexpr get_env_t @\libglobal{get_env}@{}; + + template + using @\libglobal{env_of_t}@ = decltype(get_env(declval())); + + // \ref{exec.prop}, class template \tcode{prop} + template + struct prop; + + // \ref{exec.env}, class template \tcode{env} + template<@\exposconcept{queryable}@... Envs> + struct env; + + // \ref{exec.domain.default}, execution domains + struct default_domain; + + // \ref{exec.sched}, schedulers + struct @\libglobal{scheduler_t}@ {}; + + template + concept @\libconcept{scheduler}@ = @\seebelow@; + + // \ref{exec.recv}, receivers + struct @\libglobal{receiver_t}@ {}; + + template + concept @\libconcept{receiver}@ = @\seebelow@; + + template + concept @\libconcept{receiver_of}@ = @\seebelow@; + + struct @\libglobal{set_value_t}@ { @\unspec@ }; + struct @\libglobal{set_error_t}@ { @\unspec@ }; + struct @\libglobal{set_stopped_t}@ { @\unspec@ }; + + inline constexpr set_value_t @\libglobal{set_value}@{}; + inline constexpr set_error_t @\libglobal{set_error}@{}; + inline constexpr set_stopped_t @\libglobal{set_stopped}@{}; + + // \ref{exec.opstate}, operation states + struct @\libglobal{operation_state_t}@ {}; + + template + concept @\libconcept{operation_state}@ = @\seebelow@; + + struct @\libglobal{start_t}@; + inline constexpr start_t @\libglobal{start}@{}; + + // \ref{exec.snd}, senders + struct @\libglobal{sender_t}@ {}; + + template + concept @\libconcept{sender}@ = @\seebelow@; + + template> + concept @\libconcept{sender_in}@ = @\seebelow@; + + template + concept @\libconcept{sender_to}@ = @\seebelow@; + + template + struct @\exposidnc{type-list}@; // \expos + + // \ref{exec.getcomplsigs}, completion signatures + struct get_completion_signatures_t; + inline constexpr get_completion_signatures_t get_completion_signatures {}; + + template> + requires @\libconcept{sender_in}@ + using completion_signatures_of_t = @\exposid{call-result-t}@; + + template + using @\exposidnc{decayed-tuple}@ = tuple...>; // \expos + + template + using @\exposidnc{variant-or-empty}@ = @\seebelownc@; // \expos + + template, + template class Tuple = @\exposid{decayed-tuple}@, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using value_types_of_t = @\seebelow@; + + template, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using error_types_of_t = @\seebelow@; + + template> + requires @\libconcept{sender_in}@ + constexpr bool sends_stopped = @\seebelow@; + + template + using @\exposidnc{single-sender-value-type}@ = @\seebelownc@; // \expos + + template + concept @\exposconcept{single-sender}@ = @\seebelow@; // \expos + + template<@\libconcept{sender}@ Sndr> + using tag_of_t = @\seebelow@; + + // \ref{exec.snd.transform}, sender transformations + template + requires (sizeof...(Env) <= 1) + constexpr @\libconcept{sender}@ decltype(auto) transform_sender( + Domain dom, Sndr&& sndr, const Env&... env) noexcept(@\seebelow@); + + // \ref{exec.snd.transform.env}, environment transformations + template + constexpr @\exposconcept{queryable}@ decltype(auto) transform_env( + Domain dom, Sndr&& sndr, Env&& env) noexcept; + + // \ref{exec.snd.apply}, sender algorithm application + template + constexpr decltype(auto) apply_sender( + Domain dom, Tag, Sndr&& sndr, Args&&... args) noexcept(@\seebelow@); + + // \ref{exec.connect}, the connect sender algorithm + struct @\libglobal{connect_t}@; + inline constexpr connect_t @\libglobal{connect}@{}; + + template + using @\libglobal{connect_result_t}@ = + decltype(connect(declval(), declval())); + + // \ref{exec.factories}, sender factories + struct @\libglobal{just_t}@ { @\unspec@ }; + struct @\libglobal{just_error_t}@ { @\unspec@ }; + struct @\libglobal{just_stopped_t}@ { @\unspec@ }; + struct @\libglobal{schedule_t}@ { @\unspec@ }; + + inline constexpr just_t @\libglobal{just}@{}; + inline constexpr just_error_t @\libglobal{just_error}@{}; + inline constexpr just_stopped_t @\libglobal{just_stopped}@{}; + inline constexpr schedule_t @\libglobal{schedule}@{}; + inline constexpr @\unspec@ @\libglobal{read_env}@{}; + + template<@\libconcept{scheduler}@ Sndr> + using @\libglobal{schedule_result_t}@ = decltype(schedule(declval())); + + // \ref{exec.adapt}, sender adaptors + template<@\exposconcept{class-type}@ D> + struct @\libglobal{sender_adaptor_closure}@ { }; + + struct @\libglobal{starts_on_t}@ { @\unspec@ }; + struct @\libglobal{continues_on_t}@ { @\unspec@ }; + struct @\libglobal{on_t}@ { @\unspec@ }; + struct @\libglobal{schedule_from_t}@ { @\unspec@ }; + struct @\libglobal{then_t}@ { @\unspec@ }; + struct @\libglobal{upon_error_t}@ { @\unspec@ }; + struct @\libglobal{upon_stopped_t}@ { @\unspec@ }; + struct @\libglobal{let_value_t}@ { @\unspec@ }; + struct @\libglobal{let_error_t}@ { @\unspec@ }; + struct @\libglobal{let_stopped_t}@ { @\unspec@ }; + struct @\libglobal{bulk_t}@ { @\unspec@ }; + struct @\libglobal{split_t}@ { @\unspec@ }; + struct @\libglobal{when_all_t}@ { @\unspec@ }; + struct @\libglobal{when_all_with_variant_t}@ { @\unspec@ }; + struct @\libglobal{into_variant_t}@ { @\unspec@ }; + struct @\libglobal{stopped_as_optional_t}@ { @\unspec@ }; + struct @\libglobal{stopped_as_error_t}@ { @\unspec@ }; + + inline constexpr starts_on_t @\libglobal{starts_on}@{}; + inline constexpr continues_on_t @\libglobal{continues_on}@{}; + inline constexpr on_t @\libglobal{on}@{}; + inline constexpr schedule_from_t @\libglobal{schedule_from}@{}; + inline constexpr then_t @\libglobal{then}@{}; + inline constexpr upon_error_t @\libglobal{upon_error}@{}; + inline constexpr upon_stopped_t @\libglobal{upon_stopped}@{}; + inline constexpr let_value_t @\libglobal{let_value}@{}; + inline constexpr let_error_t @\libglobal{let_error}@{}; + inline constexpr let_stopped_t @\libglobal{let_stopped}@{}; + inline constexpr bulk_t @\libglobal{bulk}@{}; + inline constexpr split_t @\libglobal{split}@{}; + inline constexpr when_all_t @\libglobal{when_all}@{}; + inline constexpr when_all_with_variant_t @\libglobal{when_all_with_variant}@{}; + inline constexpr into_variant_t @\libglobal{into_variant}@{}; + inline constexpr stopped_as_optional_t @\libglobal{stopped_as_optional}@{}; + inline constexpr stopped_as_error_t @\libglobal{stopped_as_error}@{}; + + // \ref{exec.util}, sender and receiver utilities + // \ref{exec.util.cmplsig} + template + concept @\exposconceptnc{completion-signature}@ = @\seebelownc@; // \expos + + template<@\exposconcept{completion-signature}@... Fns> + struct @\libglobal{completion_signatures}@ {}; + + template + concept @\exposconceptnc{valid-completion-signatures}@ = @\seebelownc@; // \expos + + // \ref{exec.util.cmplsig.trans} + template< + @\exposconcept{valid-completion-signatures}@ InputSignatures, + @\exposconcept{valid-completion-signatures}@ AdditionalSignatures = completion_signatures<>, + template class SetValue = @\seebelow@, + template class SetError = @\seebelow@, + @\exposconcept{valid-completion-signatures}@ SetStopped = completion_signatures> + using transform_completion_signatures = completion_signatures<@\seebelow@>; + + template< + @\libconcept{sender}@ Sndr, + class Env = env<>, + @\exposconcept{valid-completion-signatures}@ AdditionalSignatures = completion_signatures<>, + template class SetValue = @\seebelow@, + template class SetError = @\seebelow@, + @\exposconcept{valid-completion-signatures}@ SetStopped = completion_signatures> + requires @\libconcept{sender_in}@ + using transform_completion_signatures_of = + transform_completion_signatures< + completion_signatures_of_t, + AdditionalSignatures, SetValue, SetError, SetStopped>; + + // \ref{exec.run.loop}, run_loop + class run_loop; +} + +namespace std::this_thread { + // \ref{exec.consumers}, consumers + struct @\libglobal{sync_wait_t}@ { @\unspec@ }; + struct @\libglobal{sync_wait_with_variant_t}@ { @\unspec@ }; + + inline constexpr sync_wait_t @\libglobal{sync_wait}@{}; + inline constexpr sync_wait_with_variant_t @\libglobal{sync_wait_with_variant}@{}; +} + +namespace std::execution { + // \ref{exec.as.awaitable} + struct @\libglobal{as_awaitable_t}@ { @\unspec@ }; + inline constexpr as_awaitable_t @\libglobal{as_awaitable}@{}; + + // \ref{exec.with.awaitable.senders} + template<@\exposconcept{class-type}@ Promise> + struct with_awaitable_senders; +} +\end{codeblock} + +\pnum +The exposition-only type \tcode{\exposid{variant-or-empty}} +is defined as follows: +\begin{itemize} +\item +If \tcode{sizeof...(Ts)} is greater than zero, +\tcode{\exposid{variant-or-empty}} denotes \tcode{variant} +where \tcode{Us...} is the pack \tcode{decay_t...} +with duplicate types removed. +\item +Otherwise, \tcode{\exposid{variant-or-empty}} denotes +the exposition-only class type: +\begin{codeblock} +namespace std::execution { + struct @\exposidnc{empty-variant}@ { // \expos + @\exposidnc{empty-variant}@() = delete; + }; +} +\end{codeblock} +\end{itemize} + +\pnum +For types \tcode{Sndr} and \tcode{Env}, +\tcode{\exposid{single-sender-value-type}} is an alias for: +\begin{itemize} +\item +\tcode{value_types_of_t} +if that type is well-formed, +\item +Otherwise, \tcode{void} +if \tcode{value_types_of_t} is +\tcode{variant>} or \tcode{vari\-ant<>}, +\item +Otherwise, \tcode{value_types_of_t} +if that type is well-formed, +\item +Otherwise, \tcode{\exposid{single-sender-value-type}} is ill-formed. +\end{itemize} + +\pnum +The exposition-only concept \exposconcept{single-sender} is defined as follows: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{single-sender}@ = @\libconcept{sender_in}@ && + requires { + typename @\exposid{single-sender-value-type}@; + }; +} +\end{codeblock} + +\rSec1[exec.queries]{Queries} + +\rSec2[exec.fwd.env]{\tcode{forwarding_query}} + +\pnum +\tcode{forwarding_query} asks a query object +whether it should be forwarded through queryable adaptors. + +\pnum +The name \tcode{forwarding_query} denotes a query object. +For some query object \tcode{q} of type \tcode{Q}, +\tcode{forwarding_query(q)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(q.query(forwarding_query))} +if that expression is well-formed. + +\mandates +The expression above has type \tcode{bool} and +is a core constant expression if \tcode{q} is a core constant expression. +\item +Otherwise, \tcode{true} if \tcode{\libconcept{derived_from}} is \tcode{true}. +\item +Otherwise, \tcode{false}. +\end{itemize} + +\rSec2[exec.get.allocator]{\tcode{get_allocator}} + +\pnum +\tcode{get_allocator} asks a queryable object for its associated allocator. + +\pnum +The name \tcode{get_allocator} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_allocator(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_allocator))}. + +\mandates +If the expression above is well-formed, +its type satisfies +\exposconcept{simple-allocator}\iref{allocator.requirements.general}. + +\pnum +\tcode{forwarding_query(get_allocator)} is a core constant expression and +has value \tcode{true}. + +\rSec2[exec.get.stop.token]{\tcode{get_stop_token}} + +\pnum +\tcode{get_stop_token} asks a queryable object for an associated stop token. + +\pnum +The name \tcode{get_stop_token} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_stop_token(env)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_stop_token))} +if that expression is well-formed. + +\mandates +The type of the expression above satisfies \libconcept{stoppable_token}. + +\item +Otherwise, \tcode{never_stop_token\{\}}. +\end{itemize} + +\pnum +\tcode{forwarding_query(get_stop_token)} is a core constant expression and +has value \tcode{true}. + +\rSec2[exec.get.env]{\tcode{execution::get_env}} + +\pnum +\tcode{execution::get_env} is a customization point object. +For a subexpression \tcode{o}, +\tcode{execution::get_env(o)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(o).get_env())} +if that expression is well-formed. + +\mandates +The type of the expression above satisfies +\exposconcept{queryable}\iref{exec.queryable}. +\item +Otherwise, \tcode{env<>\{\}}. +\end{itemize} + +\pnum +The value of \tcode{get_env(o)} shall be valid while \tcode{o} is valid. + +\pnum +\begin{note} +When passed a sender object, +\tcode{get_env} returns the sender's associated attributes. +When passed a receiver, +\tcode{get_env} returns the receiver's associated execution environment. +\end{note} + +\rSec2[exec.get.domain]{\tcode{execution::get_domain}} + +\pnum +\tcode{get_domain} asks a queryable object +for its associated execution domain tag. + +\pnum +The name \tcode{get_domain} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_domain(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_domain))}. + +\pnum +\tcode{forwarding_query(execution::get_domain)} is +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.scheduler]{\tcode{execution::get_scheduler}} + +\pnum +\tcode{get_scheduler} asks a queryable object for its associated scheduler. + +\pnum +The name \tcode{get_scheduler} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_scheduler(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_scheduler))}. + +\mandates +If the expression above is well-formed, +its type satisfies \libconcept{scheduler}. + +\pnum +\tcode{forwarding_query(execution::get_scheduler)} is +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.delegation.scheduler]{\tcode{execution::get_delegation_scheduler}} + +\pnum +\tcode{get_delegation_scheduler} asks a queryable object for a scheduler +that can be used to delegate work to +for the purpose of forward progress delegation\iref{intro.progress}. + +\pnum +The name \tcode{get_delegation_scheduler} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_delegation_scheduler(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_delegation_scheduler))}. + +\mandates +If the expression above is well-formed, +its type satisfies \libconcept{scheduler}. + +\pnum +\tcode{forwarding_query(execution::get_delegation_scheduler)} is +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.fwd.progress]{\tcode{execution::get_forward_progress_guarantee}} + +\begin{codeblock} +namespace std::execution { + enum class @\libglobal{forward_progress_guarantee}@ { + concurrent, + parallel, + weakly_parallel + }; +} +\end{codeblock} + +\pnum +\tcode{get_forward_progress_guarantee} asks a scheduler about +the forward progress guarantee of execution agents +created by that scheduler's associated execution resource\iref{intro.progress}. + +\pnum +The name \tcode{get_forward_progress_guarantee} denotes a query object. +For a subexpression \tcode{sch}, let \tcode{Sch} be \tcode{decltype((sch))}. +If \tcode{Sch} does not satisfy \libconcept{scheduler}, +\tcode{get_forward_progress_guarantee} is ill-formed. +Otherwise, +\tcode{get_forward_progress_guarantee(sch)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(sch).query(get_forward_progress_guarantee))}, +if that expression is well-formed. + +\mandates +The type of the expression above is \tcode{forward_progress_guarantee}. +\item +Otherwise, \tcode{forward_progress_guarantee::weakly_parallel}. +\end{itemize} + +\pnum +If \tcode{get_forward_progress_guarantee(sch)} for some scheduler \tcode{sch} +returns \tcode{forward_progress_guaran\-tee::concurrent}, +all execution agents created by that scheduler's associated execution resource +shall provide the concurrent forward progress guarantee. +If it returns \tcode{forward_progress_guarantee::parallel}, +all such execution agents +shall provide at least the parallel forward progress guarantee. + +\rSec2[exec.get.compl.sched]{\tcode{execution::get_completion_scheduler}} + +\pnum +\tcode{get_completion_scheduler<\exposid{completion-tag>}} obtains +the completion scheduler associated with a completion tag +from a sender's attributes. + +\pnum +The name \tcode{get_completion_scheduler} denotes a query object template. +For a subexpression \tcode{q}, +the expression \tcode{get_completion_scheduler<\exposid{completion-tag}>(q)} +is ill-formed if \exposid{completion-tag} is not one of +\tcode{set_value_t}, \tcode{set_error_t}, or \tcode{set_stopped_t}. +Otherwise, \tcode{get_completion_scheduler<\exposid{completion-tag}>(q)} +is expression-equivalent to +\begin{codeblock} +@\exposid{MANDATE-NOTHROW}@(@\exposid{AS-CONST}@(q).query(get_completion_scheduler<@\exposid{completion-tag}@>)) +\end{codeblock} +\mandates +If the expression above is well-formed, +its type satisfies \libconcept{scheduler}. + +\pnum +Let \exposid{completion-fn} be a completion function\iref{exec.async.ops}; +let \exposid{completion-tag} be +the associated completion tag of \exposid{completion-fn}; +let \tcode{args} be a pack of subexpressions; and +let \tcode{sndr} be a subexpression +such that \tcode{\libconcept{sender}} is \tcode{true} and +\tcode{get_completion_scheduler<\exposid{completion-tag}>(get_env(sndr))} +is well-formed and denotes a scheduler \tcode{sch}. +If an asynchronous operation +created by connecting \tcode{sndr} with a receiver \tcode{rcvr} +causes the evaluation of \tcode{\exposid{completion-fn}(rcvr, args...)}, +the behavior is undefined +unless the evaluation happens on an execution agent +that belongs to \tcode{sch}'s associated execution resource. + +\pnum +The expression +\tcode{forwarding_query(get_completion_scheduler<\exposid{completion-tag}>)} +is a core constant expression and has value \tcode{true}. + +\rSec1[exec.sched]{Schedulers} + +\pnum +The \libconcept{scheduler} concept defines +the requirements of a scheduler type\iref{exec.async.ops}. +\tcode{schedule} is a customization point object +that accepts a scheduler. +A valid invocation of \tcode{schedule} is a schedule-expression. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{scheduler}@ = + @\libconcept{derived_from}@::scheduler_concept, scheduler_t> && + @\exposconcept{queryable}@ && + requires(Sch&& sch) { + { schedule(std::forward(sch)) } -> @\libconcept{sender}@; + { auto(get_completion_scheduler( + get_env(schedule(std::forward(sch))))) } + -> @\libconcept{same_as}@>; + } && + @\libconcept{equality_comparable}@> && + @\libconcept{copyable}@>; +} +\end{codeblock} + +\pnum +Let \tcode{Sch} be the type of a scheduler and +let \tcode{Env} be the type of an execution environment +for which \tcode{\libconcept{sender_in}, Env>} +is satisfied. +Then \tcode{\exposconcept{sender-in-of}, Env>} +shall be modeled. + +\pnum +No operation required by +\tcode{\libconcept{copyable}>} and +\tcode{\libconcept{equality_comparable}>} +shall exit via an exception. +None of these operations, +nor a scheduler type's \tcode{schedule} function, +shall introduce data races +as a result of potentially concurrent\iref{intro.races} invocations +of those operations from different threads. + +\pnum +For any two values \tcode{sch1} and \tcode{sch2} +of some scheduler type \tcode{Sch}, +\tcode{sch1 == sch2} shall return \tcode{true} +only if both \tcode{sch1} and \tcode{sch2} share +the same associated execution resource. + +\pnum +For a given scheduler expression \tcode{sch}, +the expression +\tcode{get_completion_scheduler(get_env(schedule(sch)))} +shall compare equal to \tcode{sch}. + +\pnum +For a given scheduler expression \tcode{sch}, +if the expression \tcode{get_domain(sch)} is well-formed, +then the expression \tcode{get_domain(get_env(schedule(sch)))} +is also well-formed and has the same type. + +\pnum +A scheduler type's destructor shall not block +pending completion of any receivers +connected to the sender objects returned from \tcode{schedule}. +\begin{note} +The ability to wait for completion of submitted function objects +can be provided by the associated execution resource of the scheduler. +\end{note} + +\rSec1[exec.recv]{Receivers} + +\rSec2[exec.recv.concepts]{Receiver concepts} + +\pnum +A receiver represents the continuation of an asynchronous operation. +The \libconcept{receiver} concept defines +the requirements for a receiver type\iref{exec.async.ops}. +The \libconcept{receiver_of} concept defines +the requirements for a receiver type that is usable as +the first argument of a set of completion operations +corresponding to a set of completion signatures. +The \tcode{get_env} customization point object is used to access +a receiver's associated environment. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{receiver}@ = + @\libconcept{derived_from}@::receiver_concept, receiver_t> && + requires(const remove_cvref_t& rcvr) { + { get_env(rcvr) } -> @\exposconcept{queryable}@; + } && + @\libconcept{move_constructible}@> && // rvalues are movable, and + @\libconcept{constructible_from}@, Rcvr>; // lvalues are copyable + + template + concept @\defexposconcept{valid-completion-for}@ = // \expos + requires (Signature* sig) { + [](Tag(*)(Args...)) + requires @\exposconcept{callable}@, Args...> + {}(sig); + }; + + template + concept @\defexposconcept{has-completions}@ = // \expos + requires (Completions* completions) { + []<@\exposconcept{valid-completion-for}@...Sigs>(completion_signatures*) + {}(completions); + }; + + template + concept @\deflibconcept{receiver_of}@ = + @\libconcept{receiver}@ && @\exposconcept{has-completions}@; +} +\end{codeblock} + +\pnum +Class types that are marked \tcode{final} do not model the \libconcept{receiver} concept. + +\pnum +Let \tcode{rcvr} be a receiver and +let \tcode{op_state} be an operation state associated with +an asynchronous operation created by connecting \tcode{rcvr} with a sender. +Let \tcode{token} be a stop token equal to +\tcode{get_stop_token(get_env(rcvr))}. +\tcode{token} shall remain valid +for the duration of the asynchronous operation's lifetime\iref{exec.async.ops}. +\begin{note} +This means that, unless it knows about further guarantees +provided by the type of \tcode{rcvr}, +the implementation of \tcode{op_state} cannot use \tcode{token} +after it executes a completion operation. +This also implies that any stop callbacks registered on token +must be destroyed before the invocation of the completion operation. +\end{note} + +\rSec2[exec.set.value]{\tcode{execution::set_value}} + +\pnum +\tcode{set_value} is a value completion function\iref{exec.async.ops}. +Its associated completion tag is \tcode{set_value_t}. +The expression \tcode{set_value(rcvr, vs...)} +for a subexpression \tcode{rcvr} and +pack of subexpressions \tcode{vs} is ill-formed +if \tcode{rcvr} is an lvalue or an rvalue of const type. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_value(vs...))}. + +\rSec2[exec.set.error]{\tcode{execution::set_error}} + +\pnum +\tcode{set_error} is an error completion function\iref{exec.async.ops}. +Its associated completion tag is \tcode{set_error_t}. +The expression \tcode{set_error(rcvr, err)} +for some \tcode{subexpressions} \tcode{rcvr} and \tcode{err} is ill-formed +if \tcode{rcvr} is an lvalue or an rvalue of const type. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_error(err))}. + +\rSec2[exec.set.stopped]{\tcode{execution::set_stopped}} + +\pnum +\tcode{set_stopped} is a stopped completion function\iref{exec.async.ops}. +Its associated completion tag is \tcode{set_stopped_t}. +The expression \tcode{set_stopped(rcvr)} +for a subexpression \tcode{rcvr} is ill-formed +if \tcode{rcvr} is an lvalue or an rvalue of const type. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_stopped())}. + +\rSec1[exec.opstate]{Operation states} + +\rSec2[exec.opstate.general]{General} + +\pnum +The \libconcept{operation_state} concept defines +the requirements of an operation state type\iref{exec.async.ops}. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{operation_state}@ = + @\libconcept{derived_from}@ && + is_object_v && + requires (O& o) { + { start(o) } noexcept; + }; +} +\end{codeblock} + +\pnum +If an \libconcept{operation_state} object is destroyed +during the lifetime of its asynchronous operation\iref{exec.async.ops}, +the behavior is undefined. +\begin{note} +The \libconcept{operation_state} concept does not impose requirements +on any operations other than destruction and \tcode{start}, +including copy and move operations. +Invoking any such operation on an object +whose type models \libconcept{operation_state} can lead to undefined behavior. +\end{note} + +\pnum +The program is ill-formed +if it performs a copy or move construction or assignment operation on +an operation state object created by connecting a library-provided sender. + +\rSec2[exec.opstate.start]{\tcode{execution::start}} + +\pnum +The name \tcode{start} denotes a customization point object +that starts\iref{exec.async.ops} +the asynchronous operation associated with the operation state object. +For a subexpression \tcode{op}, +the expression \tcode{start(op)} is ill-formed +if \tcode{op} is an rvalue. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(op.start())}. + +\pnum +If \tcode{op.start()} does not start\iref{exec.async.ops} +the asynchronous operation associated with the operation state \tcode{op}, +the behavior of calling \tcode{start(op)} is undefined. + +\rSec1[exec.snd]{Senders} + +\rSec2[exec.snd.general]{General} + +\pnum +Subclauses \ref{exec.factories} and \ref{exec.adapt} define +customizable algorithms that return senders. +Each algorithm has a default implementation. +Let \tcode{sndr} be the result of an invocation of such an algorithm or +an object equal to the result\iref{concepts.equality}, and +let \tcode{Sndr} be \tcode{decltype((sndr))}. +Let \tcode{rcvr} be a receiver of type \tcode{Rcvr} +with associated environment \tcode{env} of type \tcode{Env} +such that \tcode{\libconcept{sender_to}} is \tcode{true}. +For the default implementation of the algorithm that produced \tcode{sndr}, +connecting \tcode{sndr} to \tcode{rcvr} and +starting the resulting operation state\iref{exec.async.ops} +necessarily results in the potential evaluation\iref{basic.def.odr} of +a set of completion operations +whose first argument is a subexpression equal to \tcode{rcvr}. +Let \tcode{Sigs} be a pack of completion signatures corresponding to +this set of completion operations. +Then the type of the expression \tcode{get_completion_signatures(sndr, env)} is +a specialization of +the class template \tcode{completion_signatures}\iref{exec.util.cmplsig}, +the set of whose template arguments is \tcode{Sigs}. +If a user-provided implementation of the algorithm +that produced \tcode{sndr} is selected instead of the default, +any completion signature +that is in the set of types +denoted by \tcode{completion_signatures_of_t} and +that is not part of \tcode{Sigs} shall correspond to +error or stopped completion operations, +unless otherwise specified. + +\rSec2[exec.snd.expos]{Exposition-only entities} + +\pnum +Subclause \ref{exec.snd} makes use of the following exposition-only entities. + +\pnum +For a queryable object \tcode{env}, +\tcode{\exposid{FWD-ENV}(env)} is an expression +whose type satisfies \exposconcept{queryable} +such that for a query object \tcode{q} and +a pack of subexpressions \tcode{as}, +the expression \tcode{\exposid{FWD-ENV}(env).query(q, as...)} is ill-formed +if \tcode{forwarding_query(q)} is \tcode{false}; +otherwise, it is expression-equivalent to \tcode{env.query(q, as...)}. + +\pnum +For a query object \tcode{q} and \tcode{a} subexpression \tcode{v}, +\tcode{\exposid{MAKE-ENV}(q, v)} is an expression \tcode{env} +whose type satisfies \exposconcept{queryable} +such that the result of \tcode{env.query(q)} has +a value equal to \tcode{v}\iref{concepts.equality}. +Unless otherwise stated, +the object to which \tcode{env.query(q)} refers remains valid +while \tcode{env} remains valid. + +\pnum +For two queryable objects \tcode{env1} and \tcode{env2}, +a query object \tcode{q}, and +a pack of subexpressions \tcode{as}, +\tcode{\exposid{JOIN-ENV}(env1, env2)} is an expression \tcode{env3} +whose type satisfies \exposconcept{queryable} +such that \tcode{env3.query(q, as...)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{env1.query(q, as...)} if that expression is well-formed, +\item +otherwise, \tcode{env2.query(q, as...)} if that expression is well-formed, +\item +otherwise, \tcode{env3.query(q, as...)} is ill-formed. +\end{itemize} + +\pnum +The results of \exposid{FWD-ENV}, \exposid{MAKE-ENV}, and \exposid{JOIN-ENV} +can be context-dependent; +i.e., they can evaluate to expressions +with different types and value categories +in different contexts for the same arguments. + +\pnum +For a scheduler \tcode{sch}, +\tcode{\exposid{SCHED-ATTRS}(sch)} is an expression \tcode{o1} +whose type satisfies \exposconcept{queryable} +such that \tcode{o1.query(get_completion_scheduler)} is +an expression with the same type and value as \tcode{sch} +where \tcode{Tag} is one of \tcode{set_value_t} or \tcode{set_stopped_t}, and +such that \tcode{o1.query(get_domain)} is expression-equivalent to +\tcode{sch.query(get_domain)}. +\tcode{\exposid{SCHED-ENV}(sch)} is an expression \tcode{o2} +whose type satisfies \exposconcept{queryable} +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)}. + +\pnum +For two subexpressions \tcode{rcvr} and \tcode{expr}, +\tcode{\exposid{SET-VALUE}(rcvr, expr)} is expression-equivalent to +\tcode{(expr, set_value(std::move(rcvr)))} +if the type of \tcode{expr} is \tcode{void}; +otherwise, \tcode{set_value(std::move(rcvr), expr)}. +\tcode{\exposid{TRY-EVAL}(rcvr, expr)} is equivalent to: +\begin{codeblock} +try { + expr; +} catch(...) { + set_error(std::move(rcvr), current_exception()); +} +\end{codeblock} +if \tcode{expr} is potentially-throwing; otherwise, \tcode{expr}. +\tcode{\exposid{TRY-SET-VALUE}(rcvr, expr)} is +\begin{codeblock} +@\exposid{TRY-EVAL}@(rcvr, @\exposid{SET-VALUE}@(rcvr, expr)) +\end{codeblock} +except that \tcode{rcvr} is evaluated only once. + +\begin{itemdecl} +template + constexpr auto @\exposid{completion-domain}@(const Sndr& sndr) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{\exposid{COMPL-DOMAIN}(T)} is the type of the expression +\tcode{get_domain(get_completion_scheduler(get_env(sndr)))}. + +\pnum +\effects +If all of the types +\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} +(ignoring those types that are ill-formed), +then \tcode{\exposid{completion-domain}(sndr)} is +a default-constructed prvalue of that type. +Otherwise, \tcode{\exposid{completion-domain}(sndr)} is ill-formed. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr decltype(auto) @\exposid{query-with-default}@( + Tag, const Env& env, Default&& value) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression \tcode{Tag()(env)} +if that expression is well-formed; +otherwise, it is \tcode{static_cast(std::forward(value))}. + +\pnum +\returns +\tcode{e}. + +\pnum +\remarks +The expression in the noexcept clause is \tcode{noexcept(e)}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto @\exposid{get-domain-early}@(const Sndr& sndr) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return Domain(); +\end{codeblock} +where \tcode{Domain} is +the decayed type of the first of the following expressions that is well-formed: +\begin{itemize} +\item \tcode{get_domain(get_env(sndr))} +\item \tcode{\exposid{completion-domain}(sndr)} +\item \tcode{default_domain()} +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto @\exposid{get-domain-late}@(const Sndr& sndr, const Env& env) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{itemize} +\item +If \tcode{\exposconcept{sender-for}} is \tcode{true}, then +\begin{codeblock} +return Domain(); +\end{codeblock} +where \tcode{Domain} is the type of the following expression: +\begin{codeblock} +[] { + auto [_, sch, _] = sndr; + return @\exposid{query-or-default}@(get_domain, sch, default_domain()); +}(); +\end{codeblock} +\begin{note} +The \tcode{continues_on} algorithm works +in tandem with \tcode{schedule_from}\iref{exec.schedule.from} +to give scheduler authors a way to customize both +how to transition onto (\tcode{continues_on}) and off of (\tcode{schedule_from}) +a given execution context. +Thus, \tcode{continues_on} ignores the domain of the predecessor and +uses the domain of the destination scheduler to select a customization, +a property that is unique to \tcode{continues_on}. +That is why it is given special treatment here. +\end{note} +\item +Otherwise, +\begin{codeblock} +return Domain(); +\end{codeblock} +where \tcode{Domain} is the first of the following expressions +that is well-formed and whose type is not \tcode{void}: +\begin{itemize} +\item \tcode{get_domain(get_env(sndr))} +\item \tcode{\exposid{completion-domain}(sndr)} +\item \tcode{get_domain(env)} +\item \tcode{get_domain(get_scheduler(env))} +\item \tcode{default_domain()} +\end{itemize} +\end{itemize} +\end{itemdescr} + +\pnum +\begin{codeblock} +template<@\exposconcept{callable}@ Fun> + requires is_nothrow_move_constructible_v +struct @\exposid{emplace-from}@ { + Fun @\exposid{fun}@; // \expos + using type = @\exposid{call-result-t}@; + + constexpr operator type() && noexcept(@\exposconcept{nothrow-callable}@) { + return std::move(fun)(); + } + + constexpr type operator()() && noexcept(@\exposconcept{nothrow-callable}@) { + return std::move(fun)(); + } +}; +\end{codeblock} +\begin{note} +\exposid{emplace-from} is used to emplace non-movable types +into \tcode{tuple}, \tcode{optional}, \tcode{variant}, and similar types. +\end{note} + +\pnum +\begin{codeblock} +struct @\exposid{on-stop-request}@ { + inplace_stop_source& @\exposid{stop-src}@; // \expos + void operator()() noexcept { @\exposid{stop-src}@.request_stop(); } +}; +\end{codeblock} + +\pnum +\begin{codeblock} +template +struct @\exposid{product-type}@ { // \expos + T@$_0$@ t@$_0$@; // \expos + T@$_1$@ t@$_1$@; // \expos + @...@ + T@$_n$@ t@$_n$@; // \expos + + template + constexpr decltype(auto) @\exposid{get}@(this Self&& self) noexcept; // \expos + + template + constexpr decltype(auto) @\exposid{apply}@(this Self&& self, Fn&& fn) // \expos + noexcept(@\seebelow@); +}; +\end{codeblock} + +\pnum +\begin{note} +\exposid{product-type} is presented here in pseudo-code form +for the sake of exposition. +It can be approximated in standard \Cpp{} with a tuple-like implementation +that takes care to keep the type an aggregate +that can be used as the initializer of a structured binding declaration. +\end{note} +\begin{note} +An expression of type \exposid{product-type} is usable as +the initializer of a structured binding declaration\iref{dcl.struct.bind}. +\end{note} + +\begin{itemdecl} +template +constexpr decltype(auto) @\exposid{get}@(this Self&& self) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [...ts] = self; +return std::forward_like(ts...[I]); +\end{codeblock} +\end{itemdescr} + +\begin{codeblock} +template +constexpr decltype(auto) @\exposid{apply}@(this Self&& self, Fn&& fn) noexcept(@\seebelow@); +\end{codeblock} + +\begin{itemdescr} +\pnum +\constraints +The expression in the \tcode{return} statement below is well-formed. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [...ts] = self; +return std::forward(fn)(std::forward_like(ts)...); +\end{codeblock} + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is \tcode{true} +if the \tcode{return} statement above is not potentially throwing; +otherwise, \tcode{false}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto @\exposid{make-sender}@(Tag tag, Data&& data, Child&&... child); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The following expressions are \tcode{true}: +\begin{itemize} +\item \tcode{\libconcept{semiregular}} +\item \tcode{\exposconcept{movable-value}} +\item \tcode{(\libconcept{sender} \&\& ...)} +\end{itemize} + +\pnum +\returns +A prvalue of +type \tcode{\exposid{basic-sender}, decay_t...>} +that has been direct-list-initialized with the forwarded arguments, +where \exposid{basic-sender} is the following exposition-only class template except as noted below. +\end{itemdescr} + +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{completion-tag}@ = // \expos + @\libconcept{same_as}@ || @\libconcept{same_as}@ || @\libconcept{same_as}@; + + template class T, class... Args> + concept @\defexposconcept{valid-specialization}@ = // \expos + requires { typename T; }; + + struct @\exposid{default-impls}@ { // \expos + static constexpr auto @\exposid{get-attrs}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{get-env}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{get-state}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{start}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{complete}@ = @\seebelow@; // \expos + }; + + template + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ {}; // \expos + + template // \expos + using @\exposid{state-type}@ = decay_t<@\exposid{call-result-t}@< + decltype(@\exposid{impls-for}@>::@\exposid{get-state}@), Sndr, Rcvr&>>; + + template // \expos + using @\exposid{env-type}@ = @\exposid{call-result-t}@< + decltype(@\exposid{impls-for}@>::@\exposid{get-env}@), Index, + @\exposid{state-type}@&, const Rcvr&>; + + template + using @\exposid{child-type}@ = decltype(declval().template @\exposid{get}@()); // \expos + + template + using @\exposid{indices-for}@ = remove_reference_t::@\exposid{indices-for}@; // \expos + + template + struct @\exposid{basic-state}@ { // \expos + @\exposid{basic-state}@(Sndr&& sndr, Rcvr&& rcvr) noexcept(@\seebelow@) + : @\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 + }; + + template + requires @\exposconcept{valid-specialization}@<@\exposid{env-type}@, Index, Sndr, Rcvr> + struct @\exposid{basic-receiver}@ { // \expos + using receiver_concept = receiver_t; + + using @\exposid{tag-t}@ = tag_of_t; // \expos + using @\exposid{state-t}@ = @\exposid{state-type}@; // \expos + static constexpr const auto& @\exposid{complete}@ = @\exposid{impls-for}@<@\exposid{tag-t}@>::@\exposid{complete}@; // \expos + + template + requires @\exposconcept{callable}@ + void set_value(Args&&... args) && noexcept { + @\exposid{complete}@(Index(), op->@\exposid{state}@, op->@\exposid{rcvr}@, set_value_t(), std::forward(args)...); + } + + template + requires @\exposconcept{callable}@ + void set_error(Error&& err) && noexcept { + @\exposid{complete}@(Index(), op->@\exposid{state}@, op->@\exposid{rcvr}@, set_error_t(), std::forward(err)); + } + + void set_stopped() && noexcept + requires @\exposconcept{callable}@ { + @\exposid{complete}@(Index(), op->@\exposid{state}@, op->@\exposid{rcvr}@, set_stopped_t()); + } + + auto get_env() const noexcept -> @\exposid{env-type}@ { + return @\exposid{impls-for}@::@\exposid{get-env}@(Index(), op->@\exposid{state}@, op->@\exposid{rcvr}@); + } + + @\exposid{basic-state}@* @\exposid{op}@; // \expos + }; + + constexpr auto @\exposid{connect-all}@ = @\seebelow@; // \expos + + template + using @\exposid{connect-all-result}@ = @\exposid{call-result-t}@< // \expos + decltype(@\exposid{connect-all}@), @\exposid{basic-state}@*, Sndr, @\exposid{indices-for}@>; + + template + requires @\exposconcept{valid-specialization}@<@\exposid{state-type}@, Sndr, Rcvr> && + @\exposconcept{valid-specialization}@<@\exposid{connect-all-result}@, Sndr, Rcvr> + struct @\exposid{basic-operation}@ : @\exposid{basic-state}@ { // \expos + using operation_state_concept = operation_state_t; + using @\exposid{tag-t}@ = tag_of_t; // \expos + + @\exposid{connect-all-result}@ @\exposid{inner-ops}@; // \expos + + @\exposid{basic-operation}@(Sndr&& sndr, Rcvr&& rcvr) noexcept(@\seebelow@) // \expos + : @\exposid{basic-state}@(std::forward(sndr), std::move(rcvr)), + @\exposid{inner-ops}@(@\exposid{connect-all}@(this, std::forward(sndr), @\exposid{indices-for}@())) + {} + + void start() & noexcept { + auto& [...ops] = @\exposid{inner-ops}@; + @\exposid{impls-for}@::@\exposid{start}@(this->@\exposid{state}@, this->@\exposid{rcvr}@, ops...); + } + }; + + template + using @\exposid{completion-signatures-for}@ = @\seebelow@; // \expos + + template + struct @\exposid{basic-sender}@ : @\exposid{product-type}@ { // \expos + using sender_concept = sender_t; + using @\exposid{indices-for}@ = index_sequence_for; // \expos + + decltype(auto) get_env() const noexcept { + auto& [_, data, ...child] = *this; + return @\exposid{impls-for}@::@\exposid{get-attrs}@(data, child...); + } + + template<@\exposconcept{decays-to}@<@\exposid{basic-sender}@> Self, @\libconcept{receiver}@ Rcvr> + auto connect(this Self&& self, Rcvr rcvr) noexcept(@\seebelow@) + -> @\exposid{basic-operation}@ { + return {std::forward(self), std::move(rcvr)}; + } + + template<@\exposconcept{decays-to}@<@\exposid{basic-sender}@> Self, class Env> + auto get_completion_signatures(this Self&& self, Env&& env) noexcept + -> @\exposid{completion-signatures-for}@ { + return {}; + } + }; +} +\end{codeblock} + +\pnum +The default template argument for the \tcode{Data} template parameter +denotes an unspecified empty trivially copyable class type +that models \libconcept{semiregular}. + +\pnum +It is unspecified whether a specialization of \exposid{basic-sender} +is an aggregate. + +\pnum +An expression of type \exposid{basic-sender} is usable as +the initializer of a structured binding declaration\iref{dcl.struct.bind}. + +\pnum +The expression in the \tcode{noexcept} clause of +the constructor of \exposid{basic-state} is +\begin{codeblock} +is_nothrow_move_constructible_v && +@\exposconcept{nothrow-callable}@>::@\exposid{get-state}@), Sndr, Rcvr&> && +(@\libconcept{same_as}@<@\exposid{state-type}@, @\exposid{get-state-result}@> || + is_nothrow_constructible_v<@\exposid{state-type}@, @\exposid{get-state-result}@>) +\end{codeblock} +where \exposid{get-state-result} is +\begin{codeblock} +@\exposid{call-result-t}@>::@\exposid{get-state}@), Sndr, Rcvr&>. +\end{codeblock} + +\pnum +The object \exposid{connect-all} is initialized with +a callable object equivalent to the following lambda: +\begin{itemdecl} +[]( + @\exposid{basic-state}@* op, Sndr&& sndr, index_sequence) noexcept(@\seebelow@) + -> decltype(auto) { + auto& [_, data, ...child] = sndr; + return @\exposid{product-type}@{connect( + std::forward_like(child), + @\exposid{basic-receiver}@>{op})...}; + } +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression in the \tcode{return} statement is well-formed. + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is \tcode{true} +if the \tcode{return} statement is not potentially throwing; +otherwise, \tcode{false}. +\end{itemdescr} + +\pnum +The expression in the \tcode{noexcept} clause of +the constructor of \exposid{basic-operation} is: +\begin{codeblock} +is_nothrow_constructible_v<@\exposid{basic-state}@, Self, Rcvr> && +noexcept(@\exposid{connect-all}@(this, std::forward(sndr), @\exposid{indices-for}@())) +\end{codeblock} + +\pnum +The expression in the \tcode{noexcept} clause of +the \tcode{connect} member function of \exposid{basic-sender} is: +\begin{codeblock} +is_nothrow_constructible_v<@\exposid{basic-operation}@, Self, Rcvr> +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{get-attrs}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](const auto&, const auto&... child) noexcept -> decltype(auto) { + if constexpr (sizeof...(child) == 1) + return (@\exposid{FWD-ENV}@(get_env(child)), ...); + else + return env<>(); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{get-env}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto, auto&, const auto& rcvr) noexcept -> decltype(auto) { + return @\exposid{FWD-ENV}@(get_env(rcvr)); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept -> decltype(auto) { + auto& [_, data, ...child] = sndr; + return std::forward_like(data); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto&, auto&, auto&... ops) noexcept -> void { + (execution::start(ops), ...); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[]( + Index, auto& state, Rcvr& rcvr, Tag, Args&&... args) noexcept + -> void requires @\exposconcept{callable}@ { + static_assert(Index::value == 0); + Tag()(std::move(rcvr), std::forward(args)...); +} +\end{codeblock} + +\pnum +For a subexpression \tcode{sndr} let \tcode{Sndr} be \tcode{decltype((sndr))}. +Let \tcode{rcvr} be a receiver +with an associated environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +\tcode{\exposid{completion-signatures-for}} denotes +a specialization of \tcode{completion_signatures}, +the set of whose template arguments correspond to +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 \tcode{false}, +the type denoted by \tcode{\exposid{completion-signatures-for}}, +if any, is not a specialization of \tcode{completion_signatures}. + +\recommended +When \tcode{\libconcept{sender_in}} is \tcode{false}, +implementations are encouraged to use the type +denoted by \tcode{\exposid{completion-signatures-for}} +to communicate to users why. + +\begin{itemdecl} +template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + constexpr auto @\exposid{write-env}@(Sndr&& sndr, Env&& env); // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +\exposid{write-env} is an exposition-only sender adaptor that, +when connected with a receiver \tcode{rcvr}, +connects the adapted sender with a receiver +whose execution environment is the result of +joining the \exposconcept{queryable} argument \tcode{env} +to the result of \tcode{get_env(rcvr)}. + +\pnum +Let \exposid{write-env-t} be an exposition-only empty class type. + +\pnum +\returns +\begin{codeblock} +@\exposid{make-sender}@(@\exposid{write-env-t}@(), std::forward(env), std::forward(sndr)) +\end{codeblock} + +\pnum +\remarks +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \exposid{write-env-t} as follows: +\begin{codeblock} +template<> +struct @\exposid{impls-for}@<@\exposid{write-env-t}@> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-env}@ = + [](auto, const auto& state, const auto& rcvr) noexcept { + return @\seebelow@; + }; +}; +\end{codeblock} +Invocation of +\tcode{\exposid{impls-for}<\exposid{write-env-t}>::\exposid{get-env}} +returns an object \tcode{e} such that +\begin{itemize} +\item +\tcode{decltype(e)} models \exposconcept{queryable} and +\item +given a query object \tcode{q}, +the expression \tcode{e.query(q)} is expression-equivalent +to \tcode{state.query(q)} if that expression is valid, +otherwise, \tcode{e.query(q)} is expression-equivalent +to \tcode{get_env(rcvr).que\-ry(q)}. +\end{itemize} +\end{itemdescr} + +\rSec2[exec.snd.concepts]{Sender concepts} + +\pnum +The \libconcept{sender} concept defines +the requirements for a sender type\iref{exec.async.ops}. +The \libconcept{sender_in} concept defines +the requirements for a sender type +that can create asynchronous operations given an associated environment type. +The \libconcept{sender_to} concept defines +the requirements for a sender type +that can connect with a specific receiver type. +The \tcode{get_env} customization point object is used to access +a sender's associated attributes. +The connect customization point object is used to connect\iref{exec.async.ops} +a sender and a receiver to produce an operation state. + +\begin{codeblock} +namespace std::execution { + template + concept @\exposconcept{valid-completion-signatures}@ = @\seebelow@; // \expos + + template + concept @\defexposconcept{is-sender}@ = // \expos + @\libconcept{derived_from}@; + + template + concept @\defexposconcept{enable-sender}@ = // \expos + @\exposconcept{is-sender}@ || + @\exposconcept{is-awaitable}@>>; // \ref{exec.awaitable} + + template + concept @\deflibconcept{sender}@ = + bool(@\exposconcept{enable-sender}@>) && + requires (const remove_cvref_t& sndr) { + { get_env(sndr) } -> @\exposconcept{queryable}@; + } && + @\libconcept{move_constructible}@> && + @\libconcept{constructible_from}@, Sndr>; + + template> + concept @\deflibconcept{sender_in}@ = + @\libconcept{sender}@ && + @\exposconcept{queryable}@ && + requires (Sndr&& sndr, Env&& env) { + { get_completion_signatures(std::forward(sndr), std::forward(env)) } + -> @\exposconcept{valid-completion-signatures}@; + }; + + template + concept @\deflibconcept{sender_to}@ = + @\libconcept{sender_in}@> && + @\libconcept{receiver_of}@>> && + requires (Sndr&& sndr, Rcvr&& rcvr) { + connect(std::forward(sndr), std::forward(rcvr)); + }; +} +\end{codeblock} + +\pnum +Given a subexpression \tcode{sndr}, +let \tcode{Sndr} be \tcode{decltype((sndr))} and +let \tcode{rcvr} be a receiver +with an associated environment whose type is \tcode{Env}. +A completion operation is a \defnadj{permissible}{completion} +for \tcode{Sndr} and \tcode{Env} +if its completion signature appears in the argument list of the specialization of \tcode{completion_signatures} denoted by +\tcode{completion_signatures_of_t}. +\tcode{Sndr} and \tcode{Env} model \tcode{\libconcept{sender_in}} +if all the completion operations +that are potentially evaluated by connecting \tcode{sndr} to \tcode{rcvr} and +starting the resulting operation state +are permissible completions for \tcode{Sndr} and \tcode{Env}. + +\pnum +A type models +the exposition-only concept \defexposconcept{valid-completion-signatures} +if it denotes a specialization of +the \tcode{completion_signatures} class template. + +\pnum +The exposition-only concepts +\exposconcept{sender-of} and \exposconcept{sender-in-of} +define the requirements for a sender type +that completes with a given unique set of value result types. +\begin{codeblock} +namespace std::execution { + template + using @\exposid{value-signature}@ = set_value_t(As...); // \expos + + template + concept @\defexposconcept{sender-in-of}@ = + @\libconcept{sender_in}@ && + @\exposid{MATCHING-SIG}@( // see \ref{exec.general} + set_value_t(Values...), + value_types_of_t); + + template + concept @\defexposconcept{sender-of}@ = @\exposconcept{sender-in-of}@, Values...>; +} +\end{codeblock} + +\pnum +Let \tcode{sndr} be an expression +such that \tcode{decltype((sndr))} is \tcode{Sndr}. +The type \tcode{tag_of_t} is as follows: +\begin{itemize} +\item +If the declaration +\begin{codeblock} +auto&& [tag, data, ...children] = sndr; +\end{codeblock} +would be well-formed, \tcode{tag_of_t} is +an alias for \tcode{decltype(auto(tag))}. +\item +Otherwise, \tcode{tag_of_t} is ill-formed. +\end{itemize} + +\pnum +Let \exposconcept{sender-for} be an exposition-only concept defined as follows: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{sender-for}@ = + @\libconcept{sender}@ && + @\libconcept{same_as}@, Tag>; +} +\end{codeblock} + +\pnum +For a type \tcode{T}, +\tcode{\exposid{SET-VALUE-SIG}(T)} denotes the type \tcode{set_value_t()} +if \tcode{T} is \cv{} \tcode{void}; +otherwise, it denotes the type \tcode{set_value_t(T)}. + +\pnum +Library-provided sender types +\begin{itemize} +\item +always expose an overload of a member \tcode{connect} +that accepts an rvalue sender and +\item +only expose an overload of a member \tcode{connect} +that accepts an lvalue sender if they model \libconcept{copy_constructible}. +\end{itemize} + +\rSec2[exec.awaitable]{Awaitable helpers} + +\pnum +The sender concepts recognize awaitables as senders. +For \ref{exec}, an \defn{awaitable} is an expression +that would be well-formed as the operand of a \tcode{co_await} expression +within a given context. + +\pnum +For a subexpression \tcode{c}, +let \tcode{\exposid{GET-AWAITER}(c, p)} be expression-equivalent to +the series of transformations and conversions applied to \tcode{c} +as the operand of an \grammarterm{await-expression} in a coroutine, +resulting in lvalue \tcode{e} as described by \ref{expr.await}, +where \tcode{p} is an lvalue referring to the coroutine's promise, +which has type \tcode{Promise}. +\begin{note} +This includes the invocation of +the promise type's \tcode{await_transform} member if any, +the invocation of the \tcode{operator co_await} +picked by overload resolution if any, and +any necessary implicit conversions and materializations. +\end{note} + +\pnum +Let \exposconcept{is-awaitable} be the following exposition-only concept: +\begin{codeblock} +namespace std { + template + concept @\exposconcept{await-suspend-result}@ = @\seebelow@; // \expos + + template + concept @\defexposconcept{is-awaiter}@ = // \expos + requires (A& a, coroutine_handle h) { + a.await_ready() ? 1 : 0; + { a.await_suspend(h) } -> @\exposconcept{await-suspend-result}@; + a.await_resume(); + }; + + template + concept @\defexposconcept{is-awaitable}@ = // \expos + requires (C (*fc)() noexcept, Promise& p) { + { @\exposid{GET-AWAITER}@(fc(), p) } -> @\exposconcept{is-awaiter}@; + }; +} +\end{codeblock} + +\tcode{\defexposconcept{await-suspend-result}} is \tcode{true} +if and only if one of the following is \tcode{true}: +\begin{itemize} +\item \tcode{T} is \tcode{void}, or +\item \tcode{T} is \tcode{bool}, or +\item \tcode{T} is a specialization of \tcode{coroutine_handle}. +\end{itemize} + +\pnum +For a subexpression \tcode{c} +such that \tcode{decltype((c))} is type \tcode{C}, and +an lvalue \tcode{p} of type \tcode{Promise}, +\tcode{\exposid{await-result-\newline type}} denotes +the type \tcode{decltype(\exposid{GET-AWAITER}(c, p).await_resume())}. + +\pnum +Let \exposid{with-await-transform} be the exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{has-as-awaitable}@ = // \expos + requires (T&& t, Promise& p) { + { std::forward(t).as_awaitable(p) } -> @\exposconcept{is-awaitable}@; + }; + + template + struct @\exposid{with-await-transform}@ { // \expos + template + T&& await_transform(T&& value) noexcept { + return std::forward(value); + } + + template<@\exposconcept{has-as-awaitable}@ T> + decltype(auto) await_transform(T&& value) + noexcept(noexcept(std::forward(value).as_awaitable(declval()))) { + return std::forward(value).as_awaitable(static_cast(*this)); + } + }; +} +\end{codeblock} + +\pnum +Let \exposid{env-promise} be the exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{env-promise}@ : @\exposid{with-await-transform}@<@\exposid{env-promise}@> { // \expos + @\unspec@ get_return_object() noexcept; + @\unspec@ initial_suspend() noexcept; + @\unspec@ final_suspend() noexcept; + void unhandled_exception() noexcept; + void return_void() noexcept; + coroutine_handle<> unhandled_stopped() noexcept; + + const Env& get_env() const noexcept; + }; +} +\end{codeblock} +\begin{note} +Specializations of \exposid{env-promise} are used only for the purpose of type computation; +its members need not be defined. +\end{note} + +\rSec2[exec.domain.default]{\tcode{execution::default_domain}} + +\pnum +\begin{codeblock} +namespace std::execution { + struct @\libglobal{default_domain}@ { + template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@... Env> + requires (sizeof...(Env) <= 1) + static constexpr @\libconcept{sender}@ decltype(auto) transform_sender(Sndr&& sndr, const Env&... env) + noexcept(@\seebelow@); + + template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + static constexpr @\exposconcept{queryable}@ decltype(auto) transform_env(Sndr&& sndr, Env&& env) noexcept; + + template + static constexpr decltype(auto) apply_sender(Tag, Sndr&& sndr, Args&&... args) + noexcept(@\seebelow@); + }; +} +\end{codeblock} + +\indexlibrarymember{transform_sender}{default_domain}% +\begin{itemdecl} +template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@... Env> + requires (sizeof...(Env) <= 1) +constexpr @\libconcept{sender}@ decltype(auto) transform_sender(Sndr&& sndr, const Env&... env) + noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression +\begin{codeblock} +tag_of_t().transform_sender(std::forward(sndr), env...) +\end{codeblock} +if that expression is well-formed; +otherwise, \tcode{std::forward(sndr)}. + +\pnum +\returns +\tcode{e}. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(e)}. +\end{itemdescr} + +\indexlibrarymember{transform_env}{default_domain}% +\begin{itemdecl} +template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + constexpr @\exposconcept{queryable}@ decltype(auto) transform_env(Sndr&& sndr, Env&& env) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression +\begin{codeblock} +tag_of_t().transform_env(std::forward(sndr), std::forward(env)) +\end{codeblock} +if that expression is well-formed; +otherwise, \tcode{static_cast(std::forward(env))}. + +\pnum +\mandates +\tcode{noexcept(e)} is \tcode{true}. + +\pnum +\returns +\tcode{e}. +\end{itemdescr} + +\indexlibrarymember{apply_sender}{default_domain}% +\begin{itemdecl} +template +constexpr decltype(auto) apply_sender(Tag, Sndr&& sndr, Args&&... args) + noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression +\begin{codeblock} + Tag().apply_sender(std::forward(sndr), std::forward(args)...) +\end{codeblock} + +\pnum +\constraints +\tcode{e} is a well-formed expression. + +\pnum +\returns +\tcode{e}. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(e)}. +\end{itemdescr} + +\rSec2[exec.snd.transform]{\tcode{execution::transform_sender}} + +\indexlibraryglobal{transform_sender}% +\begin{itemdecl} +namespace std::execution { + template + requires (sizeof...(Env) <= 1) + constexpr @\libconcept{sender}@ decltype(auto) transform_sender(Domain dom, Sndr&& sndr, const Env&... env) + noexcept(@\seebelow@); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \exposid{transformed-sndr} be the expression +\begin{codeblock} +dom.transform_sender(std::forward(sndr), env...) +\end{codeblock} +if that expression is well-formed; otherwise, +\begin{codeblock} +default_domain().transform_sender(std::forward(sndr), env...) +\end{codeblock} +Let \exposid{final-sndr} be the expression \exposid{transformed-sndr} +if \exposid{transformed-sndr} and \exposid{sndr} +have the same type ignoring cv-qualifiers; +otherwise, it is +the expression \tcode{transform_sender(dom, \exposid{transformed-sndr}, env...)}. + +\pnum +\returns +\exposid{final-sndr}. + +\pnum +\remarks +The exception specification is equivalent to +\tcode{noexcept(\exposid{final-sndr})}. +\end{itemdescr} + +\rSec2[exec.snd.transform.env]{\tcode{execution::transform_env}} + +\indexlibraryglobal{transform_env}% +\begin{itemdecl} +namespace std::execution { + template + constexpr @\exposconcept{queryable}@ decltype(auto) transform_env(Domain dom, Sndr&& sndr, Env&& env) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression +\begin{codeblock} +dom.transform_env(std::forward(sndr), std::forward(env)) +\end{codeblock} +if that expression is well-formed; otherwise, +\begin{codeblock} +default_domain().transform_env(std::forward(sndr), std::forward(env)) +\end{codeblock} + +\pnum +\mandates +\tcode{noexcept(e)} is \tcode{true}. + +\pnum +\returns +\tcode{e}. +\end{itemdescr} + +\rSec2[exec.snd.apply]{\tcode{execution::apply_sender}} + +\indexlibraryglobal{apply_sender}% +\begin{itemdecl} +namespace std::execution { + template + constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) + noexcept(@\seebelow@); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $e$ be the expression +\begin{codeblock} +dom.apply_sender(Tag(), std::forward(sndr), std::forward(args)...) +\end{codeblock} +if that expression is well-formed; otherwise, +\begin{codeblock} +default_domain().apply_sender(Tag(), std::forward(sndr), std::forward(args)...) +\end{codeblock} + +\pnum +\constraints +The expression $e$ is well-formed. + +\pnum +\returns +$e$. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept($e$)}. +\end{itemdescr} + +\rSec2[exec.getcomplsigs]{\tcode{execution::get_completion_signatures}} + +\pnum +\tcode{get_completion_signatures} is a customization point object. +Let \tcode{sndr} be an expression +such that \tcode{decltype((sndr))} is \tcode{Sndr}, and +let \tcode{env} be an expression +such that \tcode{decltype((env))} is \tcode{Env}. +Let \tcode{new_sndr} be the expression +\tcode{transform_sender(decltype(\exposid{get-domain-late}(sndr, env))\{\}, sndr, env)}, and +let \tcode{NewSndr} be \tcode{decltype((new_sndr))}. +Then \tcode{get_completion_signatures(sndr, env)} is expression-equiva\-lent to +\tcode{(void(sndr), void(env), CS())} +except that \tcode{void(sndr)} and \tcode{void(env)} are +indeterminately sequenced, +where \tcode{CS} is: +\begin{itemize} +\item +\tcode{decltype(new_sndr.get_completion_signatures(env))} +if that type is well-formed, + +\item +Otherwise, \tcode{remove_cvref_t::completion_signatures} +if that type is well-formed, + +\item +Otherwise, +if \tcode{\exposconcept{is-awaitable}>} is \tcode{true}, +then: +\begin{codeblock} +completion_signatures< + @\exposid{SET-VALUE-SIG}@(@\exposid{await-result-type}@>), // \iref{exec.snd.concepts} + set_error_t(exception_ptr), + set_stopped_t()> +\end{codeblock} + +\item +Otherwise, \tcode{CS} is ill-formed. +\end{itemize} + +\pnum +Let \tcode{rcvr} be an rvalue +whose type \tcode{Rcvr} models \libconcept{receiver}, and +let \tcode{Sndr} be the type of a sender +such that \tcode{\libconcept{sender_in}>} is \tcode{true}. +Let \tcode{Sigs...} be the template arguments of +the \tcode{completion_signatures} specialization +named by \tcode{completion_signatures_of_t>}. +Let \tcode{CSO} be a completion function. +If sender \tcode{Sndr} or its operation state cause +the expression \tcode{CSO(rcvr, args...)} +to be potentially evaluated\iref{basic.def.odr} +then there shall be a signature \tcode{Sig} in \tcode{Sigs...} +such that +\begin{codeblock} +@\exposid{MATCHING-SIG}@(@\exposid{decayed-typeof}@(decltype(args)...), Sig) +\end{codeblock} +is \tcode{true}\iref{exec.general}. + +\rSec2[exec.connect]{\tcode{execution::connect}} + +\pnum +\tcode{connect} connects\iref{exec.async.ops} a sender with a receiver. + +\pnum +The name \tcode{connect} denotes a customization point object. +For subexpressions \tcode{sndr} and \tcode{rcvr}, +let \tcode{Sndr} be \tcode{decltype((sndr))} and +\tcode{Rcvr} be \tcode{decltype((rcvr))}, +let \tcode{new_sndr} be the expression +\begin{codeblock} +transform_sender(decltype(@\exposid{get-domain-late}@(sndr, get_env(rcvr))){}, sndr, get_env(rcvr)) +\end{codeblock} +and let \tcode{DS} and \tcode{DR} be +\tcode{decay_t} and \tcode{decay_t}, respectively. + +\pnum +Let \exposid{connect-awaitable-promise} be the following exposition-only class: + +\begin{codeblock} +namespace std::execution { + struct @\exposid{connect-awaitable-promise}@ : @\exposid{with-await-transform}@<@\exposid{connect-awaitable-promise}@> { + + @\exposid{connect-awaitable-promise}@(DS&, DR& rcvr) noexcept : @\exposid{rcvr}@(rcvr) {} + + suspend_always initial_suspend() noexcept { return {}; } + [[noreturn]] suspend_always final_suspend() noexcept { terminate(); } + [[noreturn]] void unhandled_exception() noexcept { terminate(); } + [[noreturn]] void return_void() noexcept { terminate(); } + + coroutine_handle<> unhandled_stopped() noexcept { + set_stopped(std::move(@\exposid{rcvr}@)); + return noop_coroutine(); + } + + @\exposid{operation-state-task}@ get_return_object() noexcept { + return @\exposid{operation-state-task}@{ + coroutine_handle<@\exposid{connect-awaitable-promise}@>::from_promise(*this)}; + } + + env_of_t get_env() const noexcept { + return execution::get_env(@\exposid{rcvr}@); + } + + private: + DR& @\exposid{rcvr}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \exposid{operation-state-task} be the following exposition-only class: +\begin{codeblock} +namespace std::execution { + struct @\exposid{operation-state-task}@ { // \expos + using operation_state_concept = operation_state_t; + using promise_type = @\exposid{connect-awaitable-promise}@; + + explicit @\exposid{operation-state-task}@(coroutine_handle<> h) noexcept : coro(h) {} + @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&&) = delete; + ~@\exposid{operation-state-task}@() { @\exposid{coro}@.destroy(); } + + void start() & noexcept { + @\exposid{coro}@.resume(); + } + + private: + coroutine_handle<> @\exposid{coro}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \tcode{V} name the type +\tcode{\exposid{await-result-type}}, +let \tcode{Sigs} name the type +\begin{codeblock} +completion_signatures< + @\exposid{SET-VALUE-SIG}@(V), // see \iref{exec.snd.concepts} + set_error_t(exception_ptr), + set_stopped_t()> +\end{codeblock} +and let \exposid{connect-awaitable} be an exposition-only coroutine +defined as follows: +\begin{codeblock} +namespace std::execution { + template + auto @\exposid{suspend-complete}@(Fun fun, Ts&&... as) noexcept { // \expos + auto fn = [&, fun]() noexcept { fun(std::forward(as)...); }; + + struct awaiter { + decltype(@\exposid{fn}@) @\exposid{fn}@; // \expos + + static constexpr bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept { @\exposid{fn}@(); } + [[noreturn]] void await_resume() noexcept { unreachable(); } + }; + return awaiter{@\exposid{fn}@}; + } + + @\exposid{operation-state-task}@ @\exposid{connect-awaitable}@(DS sndr, DR rcvr) requires @\libconcept{receiver_of}@ { + exception_ptr ep; + try { + if constexpr (@\libconcept{same_as}@) { + co_await std::move(sndr); + co_await @\exposid{suspend-complete}@(set_value, std::move(rcvr)); + } else { + co_await @\exposid{suspend-complete}@(set_value, std::move(rcvr), co_await std::move(sndr)); + } + } catch(...) { + ep = current_exception(); + } + co_await @\exposid{suspend-complete}@(set_error, std::move(rcvr), std::move(ep)); + } +} +\end{codeblock} + +\pnum +The expression \tcode{connect(sndr, rcvr)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{new_sndr.connect(rcvr)} if that expression is well-formed. + +\mandates +The type of the expression above satisfies \libconcept{operation_state}. + +\item +Otherwise, \tcode{\exposid{connect-awaitable}(new_sndr, rcvr)}. +\end{itemize} + +\mandates +\tcode{\libconcept{sender} \&\& \libconcept{receiver}} is \tcode{true}. + +\rSec2[exec.factories]{Sender factories} + +\rSec3[exec.schedule]{\tcode{execution::schedule}} + +\pnum +\tcode{schedule} obtains a schedule sender\iref{exec.async.ops} +from a scheduler. + +\pnum +The name \tcode{schedule} denotes a customization point object. +For a subexpression \tcode{sch}, +the expression \tcode{schedule(sch)} is expression-equivalent to +\tcode{sch.schedule()}. + +\pnum +\mandates +The type of \tcode{sch.schedule()} satisfies \libconcept{sender}. + +\pnum +If the expression +\begin{codeblock} +get_completion_scheduler(get_env(sch.schedule())) == sch +\end{codeblock} +is ill-formed or evaluates to \tcode{false}, +the behavior of calling \tcode{schedule(sch)} is undefined. + +\rSec3[exec.just]{\tcode{execution::just}, \tcode{execution::just_error}, \tcode{execution::just_stopped}} + +\pnum +\tcode{just}, \tcode{just_error}, and \tcode{just_stopped} are sender factories +whose asynchronous operations complete synchronously in their start operation +with a value completion operation, +an error completion operation, or +a stopped completion operation, respectively. + +\pnum +The names \tcode{just}, \tcode{just_error}, and \tcode{just_stopped} denote +customization point objects. +Let \exposid{just-cpo} be one of +\tcode{just}, \tcode{just_error}, or \tcode{just_stopped}. +For a pack of subexpressions \tcode{ts}, +let \tcode{Ts} be the pack of types \tcode{decltype((ts))}. +The expression \tcode{\exposid{just-cpo}(ts...)} is ill-formed if +\begin{itemize} +\item +\tcode{(\exposconcept{movable-value} \&\&...)} is \tcode{false}, or +\item +\exposid{just-cpo} is \tcode{just_error} and +\tcode{sizeof...(ts) == 1} is \tcode{false}, or +\item +\exposid{just-cpo} is \tcode{just_stopped} and +\tcode{sizeof...(ts) == 0} is \tcode{false}. +\end{itemize} + +Otherwise, it is expression-equivalent to +\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 +\tcode{set_value}, \tcode{set_error}, and \tcode{set_stopped}, respectively. +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \exposid{just-cpo} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{just-cpo}@>> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{start}@ = + [](auto& state, auto& rcvr) noexcept -> void { + auto& [...ts] = state; + @\exposid{set-cpo}@(std::move(rcvr), std::move(ts)...); + }; + }; +} +\end{codeblock} + +\rSec3[exec.read.env]{\tcode{execution::read_env}} + +\pnum +\tcode{read_env} is a sender factory for a sender +whose asynchronous operation completes synchronously in its start operation +with a value completion result equal to +a value read from the receiver's associated environment. + +\pnum +\tcode{read_env} is a customization point object. +For some query object \tcode{q}, +the expression \tcode{read_env(q)} is expression-equivalent to +\tcode{\exposid{make-sender}(read_env, q)}. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \tcode{read_env} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@> : @\exposid{default-impls}@ { + static constexpr auto start = + [](auto query, auto& rcvr) noexcept -> void { + @\exposid{TRY-SET-VALUE}@(rcvr, query(get_env(rcvr))); + }; + }; +} +\end{codeblock} + +\rSec2[exec.adapt]{Sender adaptors} + +\rSec3[exec.adapt.general]{General} + +\pnum +Subclause \ref{exec.adapt} specifies a set of sender adaptors. + +\pnum +The bitwise inclusive \logop{or} operator is overloaded +for the purpose of creating sender chains. +The adaptors also support function call syntax with equivalent semantics. + +\pnum +Unless otherwise specified: +\begin{itemize} +\item +A sender adaptor is prohibited from causing observable effects, +apart from moving and copying its arguments, +before the returned sender is connected with a receiver using \tcode{connect}, +and \tcode{start} is called on the resulting operation state. +\item +A parent sender\iref{exec.async.ops} with a single child sender \tcode{sndr} has +an associated attribute object equal to +\tcode{\exposid{FWD-ENV}(get_env(sndr))}\iref{exec.fwd.env}. +\item +A parent sender with more than one child sender has +an associated attributes object equal to \tcode{env<>\{\}}. +\item +When a parent sender is connected to a receiver \tcode{rcvr}, +any receiver used to connect a child sender has +an associated environment equal to \tcode{\exposid{FWD-ENV}(get_env(rcvr))}. +\item +These requirements apply to any function +that is selected by the implementation of the sender adaptor. +\end{itemize} + +\pnum +If a sender returned from a sender adaptor specified in \ref{exec.adapt} +is specified to include \tcode{set_error_t(Err)} +among its set of completion signatures +where \tcode{decay_t} denotes the type \tcode{exception_ptr}, +but the implementation does not potentially evaluate +an error completion operation with an \tcode{exception_ptr} argument, +the implementation is allowed to omit +the \tcode{exception_ptr} error completion signature from the set. + +\rSec3[exec.adapt.obj]{Closure objects} + +\pnum +A \defnadj{pipeable}{sender adaptor closure object} is a function object +that accepts one or more \libconcept{sender} arguments and returns a \libconcept{sender}. +For a pipeable sender adaptor closure object \tcode{c} and +an expression \tcode{sndr} +such that \tcode{decltype((sndr))} models \libconcept{sender}, +the following expressions are equivalent and yield a \libconcept{sender}: +\begin{codeblock} +c(sndr) +sndr | c +\end{codeblock} +Given an additional pipeable sender adaptor closure object \tcode{d}, +the expression \tcode{c | d} produces +another pipeable sender adaptor closure object \tcode{e}: + +\tcode{e} is a perfect forwarding call wrapper\iref{func.require} +with the following properties: +\begin{itemize} +\item +Its target object is an object \tcode{d2} of type \tcode{decltype(auto(d))} +direct-non-list-initialized with \tcode{d}. +\item +It has one bound argument entity, +an object \tcode{c2} of type \tcode{decltype(auto(c))} +direct-non-list-initialized with \tcode{c}. +\item +Its call pattern is \tcode{d2(c2(arg))}, +where arg is the argument used in a function call expression of \tcode{e}. +\end{itemize} +The expression \tcode{c | d} is well-formed if and only if +the initializations of the state entities\iref{func.def} of \tcode{e} +are all well-formed. + +\pnum +An object \tcode{t} of type \tcode{T} is +a pipeable sender adaptor closure object +if \tcode{T} models \tcode{\libconcept{derived_from}>}, +\tcode{T} has no other base classes +of type \tcode{sender_adaptor_closure} for any other type \tcode{U}, and +\tcode{T} does not satisfy \libconcept{sender}. + +\pnum +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, +\tcode{D} shall be complete and +model \tcode{\libconcept{derived_from}>}. +The behavior of an expression involving an object of type \cv{} \tcode{D} +as an operand to the \tcode{|} operator is undefined +if overload resolution selects a program-defined \tcode{operator|} function. + +\pnum +A \defnadj{pipeable}{sender adaptor object} is a customization point object +that accepts a \libconcept{sender} as its first argument and +returns a \libconcept{sender}. +If a pipeable sender adaptor object accepts only one argument, +then it is a pipeable sender adaptor closure object. + +\pnum +If a pipeable sender adaptor object adaptor accepts more than one argument, +then let \tcode{sndr} be an expression +such that \tcode{decltype((sndr))} models \libconcept{sender}, +let \tcode{args...} be arguments +such that \tcode{adaptor(sndr, args...)} is a well-formed expression +as specified below, and +let \tcode{BoundArgs} be a pack that denotes \tcode{decltype(auto(args))...}. +The expression \tcode{adaptor(args...)} produces +a pipeable sender adaptor closure object \tcode{f} +that is a perfect forwarding call wrapper with the following properties: +\begin{itemize} +\item +Its target object is a copy of adaptor. +\item +Its bound argument entities \tcode{bound_args} consist of +objects of types \tcode{BoundArgs...} direct-non-list-initialized with +\tcode{std::forward(args)...}, respectively. +\item +Its call pattern is \tcode{adaptor(rcvr, bound_args...)}, +where \tcode{rcvr} is +the argument used in a function call expression of \tcode{f}. +\end{itemize} +The expression \tcode{adaptor(args...)} is well-formed if and only if +the initializations of the bound argument entities of the result, +as specified above, are all well-formed. + +\rSec3[exec.starts.on]{\tcode{execution::starts_on}} + +\pnum +\tcode{starts_on} adapts an input sender into a sender +that will start on an execution agent belonging to +a particular scheduler's associated execution resource. + +\pnum +The name \tcode{starts_on} denotes a customization point object. +For subexpressions \tcode{sch} and \tcode{sndr}, +if \tcode{decltype((\newline sch))} does not satisfy \libconcept{scheduler}, or +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, +\tcode{starts_on(sch, sndr)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{starts_on(sch, sndr)} is expression-equivalent to: +\begin{codeblock} +transform_sender( + @\exposid{query-or-default}@(get_domain, sch, default_domain()), + @\exposid{make-sender}@(starts_on, sch, sndr)) +\end{codeblock} +except that \tcode{sch} is evaluated only once. + +\pnum +Let \tcode{out_sndr} and \tcode{env} be subexpressions +such that \tcode{OutSndr} is \tcode{decltype((out_sndr))}. +If \tcode{\exposconcept{sender-for}} is \tcode{false}, +then the expressions \tcode{starts_on.transform_env(out_sndr, env)} and\linebreak +\tcode{starts_on.transform_sender(out_sndr, env)} are ill-formed; otherwise +\begin{itemize} +\item +\tcode{starts_on.transform_env(out_sndr, env)} is equivalent to: +\begin{codeblock} +auto&& [_, sch, _] = out_sndr; +return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ENV}@(sch), @\exposid{FWD-ENV}@(env)); +\end{codeblock} +\item +\tcode{starts_on.transform_sender(out_sndr, env)} is equivalent to: +\begin{codeblock} +auto&& [_, sch, sndr] = out_sndr; +return let_value( + schedule(sch), + [sndr = std::forward_like(sndr)]() mutable + noexcept(is_nothrow_move_constructible_v>) { + return std::move(sndr); + }); +\end{codeblock} +\end{itemize} + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{starts_on(sch, sndr)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall start \tcode{sndr} +on an execution agent of the associated execution resource of \tcode{sch}. +If scheduling onto \tcode{sch} fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\rSec3[exec.continues.on]{\tcode{execution::continues_on}} + +\pnum +\tcode{continues_on} adapts a sender into one +that completes on the specified scheduler. + +\pnum +The name \tcode{continues_on} denotes a pipeable sender adaptor object. +For subexpressions \tcode{sch} and \tcode{sndr}, +if \tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, +\tcode{continues_on(sndr, sch)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{continues_on(sndr, sch)} is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(continues_on, sch, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. + +\pnum +The exposition-only class template \exposid{impls-for} +is specialized for \tcode{continues_on_t} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-attrs}@ = + [](const auto& data, const auto& child) noexcept -> decltype(auto) { + return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ATTRS}@(data), @\exposid{FWD-ENV}@(get_env(child))); + }; + }; +} +\end{codeblock} + +\pnum +Let \tcode{sndr} and \tcode{env} be subexpressions +such that \tcode{Sndr} is \tcode{decltype((sndr))}. +If \tcode{\exposconcept{sender-for}} is \tcode{false}, +then +the expression \tcode{continues_on.transform_sender(sndr, env)} is ill-formed; +otherwise, it is equal to: +\begin{codeblock} +auto [_, data, child] = sndr; +return schedule_from(std::move(data), std::move(child)); +\end{codeblock} +\begin{note} +This causes the \tcode{continues_on(sndr, sch)} sender to become +\tcode{schedule_from(sch, sndr)} when it is connected with a receiver +whose execution domain does not customize \tcode{continues_on}. +\end{note} + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{continues_on(sndr, sch)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +start \tcode{sndr} on the current execution agent and +execute completion operations on \tcode{out_rcvr} +on an execution agent of the execution resource associated with \tcode{sch}. +If scheduling onto \tcode{sch} fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\rSec3[exec.schedule.from]{\tcode{execution::schedule_from}} + +\pnum +\tcode{schedule_from} schedules work dependent on the completion of a sender +onto a scheduler's associated execution resource. +\begin{note} +\tcode{schedule_from} is not meant to be used in user code; +it is used in the implementation of \tcode{continues_on}. +\end{note} + +\pnum +The name \tcode{schedule_from} denotes a customization point object. +For some subexpressions \tcode{sch} and \tcode{sndr}, +let \tcode{Sch} be \tcode{decltype((sch))} and +\tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{Sch} does not satisfy \libconcept{scheduler}, or +\tcode{Sndr} does not satisfy \libconcept{sender}, +\tcode{schedule_from(sch, sndr)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{schedule_from(sch, sndr)} is expression-equivalent to: +\begin{codeblock} +transform_sender( + @\exposid{query-or-default}@(get_domain, sch, default_domain()), + @\exposid{make-sender}@(schedule_from, sch, sndr)) +\end{codeblock} +except that \tcode{sch} is evaluated only once. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \tcode{schedule_from_t} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-attrs}@ = @\seebelow@; + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{complete}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-attrs}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](const auto& data, const auto& child) noexcept -> decltype(auto) { + return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ATTRS}@(data), @\exposid{FWD-ENV}@(get_env(child))); +} +\end{codeblock} + +\pnum +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(@\seebelow@) + requires @\libconcept{sender_in}@<@\exposid{child-type}@, env_of_t> { + + auto& [_, sch, child] = sndr; + + using sched_t = decltype(auto(sch)); + using variant_t = @\seebelow@; + using receiver_t = @\seebelow@; + using operation_t = connect_result_t, receiver_t>; + constexpr bool nothrow = noexcept(connect(schedule(sch), receiver_t{nullptr})); + + struct @\exposid{state-type}@ { + Rcvr& @\exposid{rcvr}@; // \expos + variant_t @\exposid{async-result}@; // \expos + operation_t @\exposid{op-state}@; // \expos + + explicit @\exposid{state-type}@(sched_t sch, Rcvr& rcvr) noexcept(nothrow) + : @\exposid{rcvr}@(rcvr), @\exposid{op-state}@(connect(schedule(sch), receiver_t{this})) {} + }; + + return @\exposid{state-type}@{sch, rcvr}; +} +\end{codeblock} + +\pnum +Objects of the local class \exposid{state-type} can be used +to initialize a structured binding. + +\pnum +Let \tcode{Sigs} be +a pack of the arguments to the \tcode{completion_signatures} specialization +named by \tcode{completion_signatures_of_t<\exposid{child-type}, env_of_t>}. +Let \exposid{as-tuple} be an alias template +that transforms a completion signature \tcode{Tag(Args...)} into +the tuple specialization \tcode{\exposid{decayed-tuple}}. +Then \tcode{variant_t} denotes +the type \tcode{variant...>}, +except with duplicate types removed. + +\pnum +\tcode{receiver_t} is an alias for the following exposition-only class: +\begin{codeblock} +namespace std::execution { + struct @\exposid{receiver-type}@ { + using receiver_concept = receiver_t; + @\exposid{state-type}@* @\exposid{state}@; // \expos + + void set_value() && noexcept { + visit( + [this](Tuple& result) noexcept -> void { + if constexpr (!@\libconcept{same_as}@) { + auto& [tag, ...args] = result; + tag(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::move(args)...); + } + }, + @\exposid{state}@->@\exposid{async-result}@); + } + + template + void set_error(Error&& err) && noexcept { + execution::set_error(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::forward(err)); + } + + void set_stopped() && noexcept { + execution::set_stopped(std::move(@\exposid{state}@->@\exposid{rcvr}@)); + } + + decltype(auto) get_env() const noexcept { + return @\exposid{FWD-ENV}@(execution::get_env(@\exposid{state}@->@\exposid{rcvr}@)); + } + }; +} +\end{codeblock} + +\pnum +The expression in the \tcode{noexcept} clause of the lambda is \tcode{true} +if the construction of the returned \exposid{state-type} object +is not potentially throwing; +otherwise, \tcode{false}. + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept + -> void { + using result_t = @\exposid{decayed-tuple}@; + constexpr bool nothrow = is_nothrow_constructible_v; + + try { + state.@\exposid{async-result}@.template emplace(Tag(), std::forward(args)...); + } catch (...) { + if constexpr (!nothrow) { + set_error(std::move(rcvr), current_exception()); + return; + } + } + start(state.@\exposid{op-state}@); +}; +\end{codeblock} + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{schedule_from(sch, sndr)} or one equal to such, +and let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +start \tcode{sndr} on the current execution agent and +execute completion operations on \tcode{out_rcvr} +on an execution agent of the execution resource associated with \tcode{sch}. +If scheduling onto \tcode{sch} fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\rSec3[exec.on]{\tcode{execution::on}} + +\pnum +The \tcode{on} sender adaptor has two forms: +\begin{itemize} +\item +\tcode{on(sch, sndr)}, +which starts a sender \tcode{sndr} on an execution agent +belonging to a scheduler \tcode{sch}'s associated execution resource and +that, upon \tcode{sndr}'s completion, +transfers execution back to the execution resource +on which the \tcode{on} sender was started. +\item +\tcode{on(sndr, sch, closure)}, +which upon completion of a sender \tcode{sndr}, +transfers execution to an execution agent +belonging to a scheduler \tcode{sch}'s associated execution resource, +then executes a sender adaptor closure \tcode{closure} +with the async results of the sender, and +that then transfers execution back to the execution resource +on which \tcode{sndr} completed. +\end{itemize} + +\pnum +The name \tcode{on} denotes a pipeable sender adaptor object. +For subexpressions \tcode{sch} and \tcode{sndr}, +\tcode{on(sch, sndr)} is ill-formed if any of the following is \tcode{true}: +\begin{itemize} +\item +\tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or +\item +\tcode{decltype((sndr))} does not satisfy \libconcept{sender} and +\tcode{sndr} is not +a pipeable sender adaptor closure object\iref{exec.adapt.obj}, or +\item +\tcode{decltype((sndr))} satisfies \libconcept{sender} and +\tcode{sndr }is also a pipeable sender adaptor closure object. +\end{itemize} + +\pnum +Otherwise, if \tcode{decltype((sndr))} satisfies \libconcept{sender}, +the expression \tcode{on(sch, sndr)} is expression-equivalent to: +\begin{codeblock} +transform_sender( + @\exposid{query-or-default}@(get_domain, sch, default_domain()), + @\exposid{make-sender}@(on, sch, sndr)) +\end{codeblock} +except that \tcode{sch} is evaluated only once. + +\pnum +For subexpressions \tcode{sndr}, \tcode{sch}, and \tcode{closure}, if +\begin{itemize} +\item +\tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or +\item +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\item +\tcode{closure} is not a pipeable sender adaptor closure object\iref{exec.adapt.obj}, +\end{itemize} +the expression \tcode{on(sndr, sch, closure)} is ill-formed; +otherwise, it is expression-equivalent to: +\begin{codeblock} +transform_sender( + @\exposid{get-domain-early}@(sndr), + @\exposid{make-sender}@(on, @\exposid{product-type}@{sch, closure}, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. + +\pnum +Let \tcode{out_sndr} and \tcode{env} be subexpressions, +let \tcode{OutSndr} be \tcode{decltype((out_sndr))}, and +let \tcode{Env} be \tcode{decltype((\linebreak env))}. +If \tcode{\exposconcept{sender-for}} is \tcode{false}, +then the expressions \tcode{on.transform_env(out_sndr, env)} and +\tcode{on.transform_sender(out_sndr, env)} are ill-formed. + +\pnum +Otherwise: +Let \exposid{not-a-scheduler} be an unspecified empty class type, and +let \exposid{not-a-sender} be the exposition-only type: +\begin{codeblock} +struct @\exposid{not-a-sender}@ { + using sender_concept = sender_t; + + auto get_completion_signatures(auto&&) const { + return @\seebelow@; + } +}; +\end{codeblock} +where the member function \tcode{get_completion_signatures} returns +an object of a type that is not +a specialization of the \tcode{completion_signatures} class template. + +\pnum +The expression \tcode{on.transform_env(out_sndr, env)} +has effects equivalent to: +\begin{codeblock} +auto&& [_, data, _] = out_sndr; +if constexpr (@\libconcept{scheduler}@) { + return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ENV}@(std::forward_like(data)), @\exposid{FWD-ENV}@(std::forward(env))); +} else { + return std::forward(env); +} +\end{codeblock} + +\pnum +The expression \tcode{on.transform_sender(out_sndr, env)} +has effects equivalent to: +\begin{codeblock} +auto&& [_, data, child] = out_sndr; +if constexpr (@\libconcept{scheduler}@) { + auto orig_sch = + @\exposid{query-with-default}@(get_scheduler, env, @\exposid{not-a-scheduler}@()); + + if constexpr (@\libconcept{same_as}@) { + return @\exposid{not-a-sender}@{}; + } else { + return continues_on( + starts_on(std::forward_like(data), std::forward_like(child)), + std::move(orig_sch)); + } +} else { + auto& [sch, closure] = data; + auto orig_sch = @\exposid{query-with-default}@( + get_completion_scheduler, + get_env(child), + @\exposid{query-with-default}@(get_scheduler, env, @\exposid{not-a-scheduler}@())); + + if constexpr (@\libconcept{same_as}@) { + return @\exposid{not-a-sender}@{}; + } else { + return @\exposid{write-env}@( + continues_on( + std::forward_like(closure)( + continues_on( + @\exposid{write-env}@(std::forward_like(child), @\exposid{SCHED-ENV}@(orig_sch)), + sch)), + orig_sch), + @\exposid{SCHED-ENV}@(sch)); + } +} +\end{codeblock} + +\pnum +\recommended +Implementations should use +the return type of \tcode{\exposid{not-a-sender}::get_completion_signatures} +to inform users that their usage of \tcode{on} is incorrect +because there is no available scheduler onto which to restore execution. + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{on(sch, sndr)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +\begin{itemize} +\item +remember the current scheduler, \tcode{get_scheduler(get_env(rcvr))}; +\item +start \tcode{sndr} on an execution agent belonging to +sch's associated execution resource; +\item +upon \tcode{sndr}'s completion, +transfer execution back to the execution resource +associated with the scheduler remembered in step 1; and +\item +forward \tcode{sndr}'s async result to \tcode{out_rcvr}. +\end{itemize} +If any scheduling operation fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{on(sndr, sch, closure)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +\begin{itemize} +\item +remember the current scheduler, +which is the first of the following expressions that is well-formed: +\begin{itemize} +\item \tcode{get_completion_scheduler(get_env(sndr))} +\item \tcode{get_scheduler(get_env(rcvr))}; +\end{itemize} +\item +start \tcode{sndr} on the current execution agent; +\item +upon \tcode{sndr}'s completion, +transfer execution to an agent +owned by sch's associated execution resource; +\item +forward \tcode{sndr}'s async result as if by +connecting and starting a sender \tcode{closure(S)}, +where \tcode{S} is a sender +that completes synchronously with \tcode{sndr}'s async result; and +\item +upon completion of the operation started in the previous step, +transfer execution back to the execution resource +associated with the scheduler remembered in step 1 and +forward the operation's async result to \tcode{out_rcvr}. +\end{itemize} +If any scheduling operation fails, +an error completion on \tcode{out_rcvr} shall be executed on +an unspecified execution agent. + +\rSec3[exec.then]{\tcode{execution::then}, \tcode{execution::upon_error}, \tcode{execution::upon_stopped}} + +\pnum +\tcode{then} attaches an invocable as a continuation +for an input sender's value completion operation. +\tcode{upon_error} and \tcode{upon_stopped} do the same +for the error and stopped completion operations, respectively, +sending the result of the invocable as a value completion. + +\pnum +The names \tcode{then}, \tcode{upon_error}, and \tcode{upon_stopped} +denote pipeable sender adaptor objects. +Let the expression \exposid{then-cpo} be one of +\tcode{then}, \tcode{upon_error}, or \tcode{upon_stopped}. +For subexpressions \tcode{sndr} and \tcode{f}, +if \tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +\tcode{\exposid{then-cpo}(\linebreak sndr, f) }is ill-formed. + +\pnum +Otherwise, +the expression \tcode{\exposid{then-cpo}(sndr, f)} is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(@\exposid{then-cpo}@, f, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. + +\pnum +For \tcode{then}, \tcode{upon_error}, and \tcode{upon_stopped}, +let \exposid{set-cpo} be +\tcode{set_value}, \tcode{set_error}, and \tcode{set_stopped}, respectively. +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \exposid{then-cpo} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{then-cpo}@>> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{complete}@ = + [] + (auto, auto& fn, auto& rcvr, Tag, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@>) { + @\exposid{TRY-SET-VALUE}@(rcvr, + invoke(std::move(fn), std::forward(args)...)); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } + }; + }; +} +\end{codeblock} + +\pnum +The expression \tcode{\exposid{then-cpo}(sndr, f)} has undefined behavior +unless it returns a sender \tcode{out_sndr} that +\begin{itemize} +\item +invokes \tcode{f} or a copy of such +with the value, error, or stopped result datums of \tcode{sndr} +for \tcode{then}, \tcode{upon_error}, and \tcode{upon_stopped}, respectively, +using the result value of \tcode{f} as \tcode{out_sndr}'s value completion, and +\item +forwards all other completion operations unchanged. +\end{itemize} + +\rSec3[exec.let]{\tcode{execution::let_value}, \tcode{execution::let_error}, \tcode{execution::let_stopped}} + +\pnum +\tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped} transform +a sender's value, error, and stopped completions, respectively, +into a new child asynchronous operation +by passing the sender's result datums to a user-specified callable, +which returns a new sender that is connected and started. + +\pnum +For \tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped}, +let \exposid{set-cpo} be +\tcode{set_value}, \tcode{set_error}, and \tcode{set_stopped}, respectively. +Let the expression \exposid{let-cpo} be one of +\tcode{let_value}, \tcode{let_error}, or \tcode{let_stopped}. +For a subexpression \tcode{sndr}, +let \tcode{\exposid{let-env}(sndr)} be expression-equivalent to +the first well-formed expression below: +\begin{itemize} +\item +\tcode{\exposid{SCHED-ENV}(get_completion_scheduler<\exposid{decayed-typeof}<\exposid{set-cpo}>>(get_env(sndr)))} +\item +\tcode{\exposid{MAKE-ENV}(get_domain, get_domain(get_env(sndr)))} +\item +\tcode{(void(sndr), env<>\{\})} +\end{itemize} + +\pnum +The names \tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped} denote +pipeable sender adaptor objects. +For subexpressions \tcode{sndr} and \tcode{f}, +let \tcode{F} be the decayed type of \tcode{f}. +If \tcode{decltype((sndr))} does not satisfy \libconcept{sender} or +if \tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +the expression \tcode{\exposid{let-cpo}(sndr, f)} is ill-formed. +If \tcode{F} does not satisfy \libconcept{invocable}, +the expression \tcode{let_stopped(sndr, f)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{\exposid{let-cpo}(sndr, f)} is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(@\exposid{let-cpo}@, f, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \exposid{let-cpo} as follows: +\begin{codeblock} +namespace std::execution { + template + void @\exposid{let-bind}@(State& state, Rcvr& rcvr, Args&&... args); // \expos + + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{let-cpo}@>> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{complete}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +Let \exposid{receiver2} denote the following exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{receiver2}@ { + using receiver_concept = receiver_t; + + template + void set_value(Args&&... args) && noexcept { + execution::set_value(std::move(@\exposid{rcvr}@), std::forward(args)...); + } + + template + void set_error(Error&& err) && noexcept { + execution::set_error(std::move(@\exposid{rcvr}@), std::forward(err)); + } + + void set_stopped() && noexcept { + execution::set_stopped(std::move(@\exposid{rcvr}@)); + } + + decltype(auto) get_env() const noexcept { + return @\seebelow@; + } + + Rcvr& @\exposid{rcvr}@; // \expos + Env @\exposid{env}@; // \expos + }; +} +\end{codeblock} +Invocation of the function \tcode{\exposid{receiver2}::get_env} +returns an object \tcode{e} such that +\begin{itemize} +\item +\tcode{decltype(e)} models \exposconcept{queryable} and +\item +given a query object \tcode{q}, +the expression \tcode{e.query(q)} is expression-equivalent +to \tcode{\exposid{env}.query(q)} if that expression is valid, +otherwise \tcode{e.query(q)} is expression-equivalent +to \tcode{get_env(\exposid{rcvr}).query(q)}. +\end{itemize} + +\pnum +\tcode{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>::\exposid{get-state}} +is initialized with a callable object equivalent to the following: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) requires @\seebelow@ { + auto& [_, fn, child] = sndr; + using fn_t = decay_t; + using env_t = decltype(@\exposid{let-env}@(child)); + using args_variant_t = @\seebelow@; + using ops2_variant_t = @\seebelow@; + + struct @\exposid{state-type}@ { + fn_t @\exposid{fn}@; // \expos + env_t @\exposid{env}@; // \expos + args_variant_t @\exposid{args}@; // \expos + ops2_variant_t @\exposid{ops2}@; // \expos + }; + return @\exposid{state-type}@{std::forward_like(fn), @\exposid{let-env}@(child), {}, {}}; +} +\end{codeblock} + +\pnum +Let \tcode{Sigs} be a pack of the arguments +to the \tcode{completion_signatures} specialization named by +\tcode{completion_signatures_of_t<\exposid{child-type}, env_of_t>}. +Let \tcode{LetSigs} be a pack of those types in \tcode{Sigs} +with a return type of \tcode{\exposid{decayed-typeof}<\exposid{set-cpo}>}. +Let \exposid{as-tuple} be an alias template +such that \tcode{\exposid{as-tuple}<\linebreak Tag(Args...)>} denotes +the type \tcode{\exposid{decayed-tuple}}. +Then \tcode{args_variant_t} denotes +the type \tcode{variant...>} +except with duplicate types removed. + +\pnum +Given a type \tcode{Tag} and a pack \tcode{Args}, +let \exposid{as-sndr2} be an alias template +such that \tcode{\exposid{as-sndr2}} denotes +the type \tcode{\exposid{call-result-t}\&...>}. +Then \tcode{ops2_variant_t} denotes +the type +\begin{codeblock} +variant, @\exposid{receiver2}@>...> +\end{codeblock} +except with duplicate types removed. + +\pnum +The \grammarterm{requires-clause} constraining the above lambda is satisfied +if and only if +the types \tcode{args_variant_t} and \tcode{ops2_variant_t} are well-formed. + +\pnum +The exposition-only function template \exposid{let-bind} +has effects equivalent to: +\begin{codeblock} +using args_t = @\exposid{decayed-tuple}@; +auto mkop2 = [&] { + return connect( + apply(std::move(state.fn), + state.args.template emplace(std::forward(args)...)), + @\exposid{receiver2}@{rcvr, std::move(state.env)}); +}; +start(state.ops2.template emplace(@\exposid{emplace-from}@{mkop2})); +\end{codeblock} + +\pnum +\tcode{\exposid{impls-for}<\exposid{decayed-typeof}>::\exposid{complete}} +is initialized with a callable object equivalent to the following: +\begin{codeblock} +[] + (auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@>) { + @\exposid{TRY-EVAL}@(rcvr, @\exposid{let-bind}@(state, rcvr, std::forward(args)...)); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } + } +\end{codeblock} + +\pnum +Let \tcode{sndr} and \tcode{env} be subexpressions, and +let \tcode{Sndr} be \tcode{decltype((sndr))}. +If +\tcode{\exposconcept{sender-for}>} +is \tcode{false}, +then the expression \tcode{\exposid{let-cpo}.transform_env(sndr, env)} +is ill-formed. +Otherwise, it is equal to +\tcode{\exposid{JOIN-ENV}(\exposid{let-env}(sndr), \exposid{FWD-ENV}(env))}. + +\pnum +Let the subexpression \tcode{out_sndr} denote +the result of the invocation \tcode{\exposid{let-cpo}(sndr, f)} or +an object equal to such, and +let the subexpression \tcode{rcvr} denote a receiver +such that the expression \tcode{connect(out_sndr, rcvr)} is well-formed. +The expression \tcode{connect(out_sndr, rcvr)} has undefined behavior +unless it creates an asynchronous operation\iref{exec.async.ops} that, +when started: +\begin{itemize} +\item +invokes \tcode{f} when \exposid{set-cpo} is called +with \tcode{sndr}'s result datums, +\item +makes its completion dependent on +the completion of a sender returned by \tcode{f}, and +\item +propagates the other completion operations sent by \tcode{sndr}. +\end{itemize} + +\rSec3[exec.bulk]{\tcode{execution::bulk}} + +\pnum +\tcode{bulk} runs a task repeatedly for every index in an index space. + +The name \tcode{bulk} denotes a pipeable sender adaptor object. +For subexpressions \tcode{sndr}, \tcode{shape}, and \tcode{f}, +let \tcode{Shape} be \tcode{decltype(auto(shape))}. +If +\begin{itemize} +\item +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\item +\tcode{Shape} does not satisfy \libconcept{integral}, or +\item +\tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +\end{itemize} +\tcode{bulk(sndr, shape, f)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{bulk(sndr, shape, f)} is expression-equivalent to: + +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(bulk, @\exposid{product-type}@{shape, f}, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \tcode{bulk_t} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{complete}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[] + (Index, State& state, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void requires @\seebelow@ { + if constexpr (@\libconcept{same_as}@) { + auto& [shape, f] = state; + constexpr bool nothrow = noexcept(f(auto(shape), args...)); + @\exposid{TRY-EVAL}@(rcvr, [&]() noexcept(nothrow) { + for (decltype(auto(shape)) i = 0; i < shape; ++i) { + f(auto(i), args...); + } + Tag()(std::move(rcvr), std::forward(args)...); + }()); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } + } +\end{codeblock} + +\pnum +The expression in the \grammarterm{requires-clause} of the lambda above +is \tcode{true} if and only +if \tcode{Tag} denotes a type other than \tcode{set_value_t} or +if the expression \tcode{f(auto(shape), args...)} is well-formed. + +\pnum +Let the subexpression \tcode{out_sndr} denote +the result of the invocation \tcode{bulk(sndr, shape, f)} or +an object equal to such, and +let the subexpression \tcode{rcvr} denote a receiver +such that the expression \tcode{connect(out_sndr, rcvr)} is well-formed. +The expression \tcode{connect(out_sndr, rcvr)} has undefined behavior +unless it creates an asynchronous operation\iref{exec.async.ops} that, +when started, +\begin{itemize} +\item +on a value completion operation, +invokes \tcode{f(i, args...)} +for every \tcode{i} of type \tcode{Shape} in \range{\tcode{0}}{\tcode{shape}}, +where \tcode{args} is a pack of lvalue subexpressions +referring to the value completion result datums of the input sender, and +\item +propagates all completion operations sent by \tcode{sndr}. +\end{itemize} + +\rSec3[exec.split]{\tcode{execution::split}} + +\pnum +\tcode{split} adapts an arbitrary sender +into a sender that can be connected multiple times. + +\pnum +Let \exposid{split-env} be the type of an environment +such that, given an instance \tcode{env}, +the expression \tcode{get_stop_token(env)} is well-formed and +has type \tcode{inplace_stop_token.} + +\pnum +The name \tcode{split} denotes a pipeable sender adaptor object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{\libconcept{sender_in}} is \tcode{false}, +\tcode{split(sndr)} is ill-formed. + +\pnum +Otherwise, the expression \tcode{split(sndr)} is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(split, {}, sndr)) +\end{codeblock} +except that \tcode{sndr} is evaluated only once. +\begin{note} +The default implementation of \tcode{transform_sender} +will have the effect of connecting the sender to a receiver. +It will return a sender with a different tag type. +\end{note} + +\pnum +Let \exposid{local-state} denote the following exposition-only class template: + +\begin{codeblock} +namespace std::execution { + struct @\exposid{local-state-base}@ { // \expos + virtual ~@\exposid{local-state-base}@() = default; + virtual void @\exposid{notify}@() noexcept = 0; // \expos + }; + + template + struct @\exposid{local-state}@ : @\exposid{local-state-base}@ { // \expos + using @\exposid{on-stop-callback}@ = // \expos + stop_callback_for_t>, @\exposid{on-stop-request}@>; + + @\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept; + ~@\exposid{local-state}@(); + + void @\exposid{notify}@() noexcept override; + + private: + optional<@\exposid{on-stop-callback}@> @\exposid{on_stop}@; // \expos + @\exposid{shared-state}@* @\exposid{sh_state}@; // \expos + Rcvr* @\exposid{rcvr}@; // \expos + }; +} +\end{codeblock} + +\begin{itemdecl} +@\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [_, data, _] = sndr; +this->@\exposid{sh_state}@ = data.sh_state.get(); +this->@\exposid{sh_state}@->@\exposid{inc-ref}@(); +this->@\exposid{rcvr}@ = addressof(rcvr); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +~@\exposid{local-state}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +sh_state->@\exposid{dec-ref}@(); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{notify}@() noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{on_stop}@.reset(); +visit( + [this](const auto& tupl) noexcept -> void { + apply( + [this](auto tag, const auto&... args) noexcept -> void { + tag(std::move(*@\exposid{rcvr}@), args...); + }, + tupl); + }, + @\exposid{sh_state}@->result); +\end{codeblock} +\end{itemdescr} + +\pnum +Let \exposid{split-receiver} denote +the following exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{split-receiver}@ { // \expos + using receiver_concept = receiver_t; + + template + void @\exposid{complete}@(Tag, Args&&... args) noexcept { // \expos + using tuple_t = @\exposid{decayed-tuple}@; + try { + @\exposid{sh_state}@->result.template emplace(Tag(), std::forward(args)...); + } catch (...) { + using tuple_t = tuple; + @\exposid{sh_state}@->result.template emplace(set_error, current_exception()); + } + @\exposid{sh_state}@->notify(); + } + + template + void set_value(Args&&... args) && noexcept { + @\exposid{complete}@(execution::set_value, std::forward(args)...); + } + + template + void set_error(Error&& err) && noexcept { + @\exposid{complete}@(execution::set_error, std::forward(err)); + } + + void set_stopped() && noexcept { + @\exposid{complete}@(execution::set_stopped); + } + + struct @\exposid{env}@ { // \expos + @\exposid{shared-state}@* @\exposid{sh-state}@; // \expos + + inplace_stop_token query(get_stop_token_t) const noexcept { + return @\exposid{sh-state}@->stop_src.get_token(); + } + }; + + @\exposid{env}@ get_env() const noexcept { + return @\exposid{env}@{@\exposid{sh_state}@}; + } + + @\exposid{shared-state}@* @\exposid{sh_state}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \exposid{shared-state} denote the following exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{shared-state}@ { + using @\exposid{variant-type}@ = @\seebelow@; // \expos + using @\exposid{state-list-type}@ = @\seebelow@; // \expos + + explicit @\exposid{shared-state}@(Sndr&& sndr); + + void @\exposid{start-op}@() noexcept; // \expos + void @\exposid{notify}@() noexcept; // \expos + void @\exposid{inc-ref}@() noexcept; // \expos + void @\exposid{dec-ref}@() noexcept; // \expos + + inplace_stop_source @\exposid{stop_src}@{}; // \expos + @\exposid{variant-type}@ @\exposid{result}@{}; // \expos + @\exposid{state-list-type}@ @\exposid{waiting_states}@; // \expos + atomic @\exposid{completed}@{false}; // \expos + atomic @\exposid{ref_count}@{1}; // \expos + connect_result_t> @\exposid{op_state}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \tcode{Sigs} be a pack of the arguments +to the \tcode{completion_signatures} specialization +named by \tcode{completion_signatures_of_t}. +For type \tcode{Tag} and pack \tcode{Args}, +let \exposid{as-tuple} be an alias template +such that \tcode{\exposid{as-tuple}} denotes +the type \tcode{\exposid{decayed-tuple}}. +Then \exposid{variant-type} denotes the type +\begin{codeblock} +variant, tuple, @\exposid{as-tuple}@...> +\end{codeblock} +but with duplicate types removed. + +\pnum +Let \exposid{state-list-type} be a type +that stores a list of pointers to \exposid{local-state-base} objects and +that permits atomic insertion. + +\begin{itemdecl} +explicit @\exposid{shared-state}@(Sndr&& sndr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{op_state} with the result of +\tcode{connect(std::forward(sndr), \exposid{split-re\-ceiver}\{this\})}. + +\pnum +\ensures +\exposid{waiting_states} is empty, and \exposid{completed} is \tcode{false}. +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{start-op}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Evaluates \tcode{\exposid{inc-ref}()}. +If \tcode{stop_src.stop_requested()} is \tcode{true}, +evaluates \tcode{\exposid{notify}()}; +otherwise, evaluates \tcode{start(\exposid{op_state})}. +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{notify}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Atomically does the following: +\begin{itemize} +\item +Sets \tcode{completed} to \tcode{true}, and +\item +Exchanges \tcode{waiting_states} with an empty list, +storing the old value in a local \tcode{prior_states}. +\end{itemize} +Then, for each pointer \tcode{p} in \tcode{prior_states}, +evaluates \tcode{p->\exposid{notify}()}. +Finally, evaluates \tcode{\exposid{dec-ref}()}. +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{inc-ref}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Increments \exposid{ref_count}. +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{dec-ref}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Decrements \exposid{ref_count}. +If the new value of \exposid{ref_count} is \tcode{0}, +calls \tcode{delete this}. + +\pnum +\sync +If an evaluation of \tcode{\exposid{dec-ref}()} does not +decrement the \tcode{ref_count} to \tcode{0} then +synchronizes with the evaluation of \tcode{dec-ref()} +that decrements \tcode{ref_count} to \tcode{0}. +\end{itemdescr} + +\pnum +Let \exposid{split-impl-tag} be an empty exposition-only class type. +Given an expression \tcode{sndr}, +the expression \tcode{split.transform_sender(sndr)} is equivalent to: +\begin{codeblock} +auto&& [tag, _, child] = sndr; +auto* sh_state = new @\exposid{shared-state}@{std::forward_like(child)}; +return @\exposid{make-sender}@(@\exposid{split-impl-tag}@(), @\exposid{shared-wrapper}@{sh_state, tag}); +\end{codeblock} +where \exposid{shared-wrapper} is an exposition-only class +that manages the reference count of the \exposid{shared-state} object +pointed to by sh_state. +\exposid{shared-wrapper} models \libconcept{copyable} +with move operations nulling out the moved-from object, +copy operations incrementing the reference count +by calling \tcode{sh_state->\exposid{inc-ref}()}, and +assignment operations performing a copy-and-swap operation. +The destructor has no effect if sh_state is null; +otherwise, it decrements the reference count +by evaluating \tcode{sh_state->\exposid{dec-ref}()}. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \exposid{split-impl-tag} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{split-impl-tag}@> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{start}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +The member +\tcode{\exposid{impls-for}<\exposid{split-impl-tag}>::\exposid{get-state}} +is initialized with a callable object equivalent to +the following lambda expression: +\begin{codeblock} +[](Sndr&& sndr, auto& rcvr) noexcept { + return @\exposid{local-state}@{std::forward(sndr), rcvr}; +} +\end{codeblock} + +\pnum +The member +\tcode{\exposid{impls-for}<\exposid{split-impl-tag}>::\exposid{start}} +is initialized with a callable object +that has a function call operator equivalent to the following: +\begin{codeblock} +template +void operator()(@\exposid{local-state}@& state, Rcvr& rcvr) const noexcept; +\end{codeblock} + +\effects +If \tcode{state.\exposid{sh_state}->\exposid{completed}} is \tcode{true}, +evaluates \tcode{state.\exposid{notify}()} and returns. +Otherwise, does the following in order: +\begin{itemize} +\item +Evaluates +\begin{codeblock} +state.@\exposid{on_stop}@.emplace( + get_stop_token(get_env(rcvr)), + @\exposid{on-stop-request}@{state.@\exposid{sh_state}@->@\exposid{stop_src}@}); +\end{codeblock} +\item +Then atomically does the following: +\begin{itemize} +\item +Reads the value \tcode{c} of +\tcode{state.\exposid{sh_state}->\exposid{completed}}, and +\item +Inserts \tcode{addressof(state)} into +\tcode{state.\exposid{sh_state}->\exposid{waiting_states}} +if \tcode{c} is \tcode{false}. +\end{itemize} +\item +If \tcode{c} is \tcode{true}, +calls \tcode{state.\exposid{notify}()} and returns. +\item +Otherwise, +if \tcode{addressof(state)} is the first item added to +\tcode{state.\exposid{sh_state}->\exposid{waiting_states}}, +evaluates \tcode{state.\exposid{sh_state}->\exposid{start-op}()}. +\end{itemize} + +\rSec3[exec.when.all]{\tcode{execution::when_all}} + +\pnum +\tcode{when_all} and \tcode{when_all_with_variant} +both adapt multiple input senders into a sender +that completes when all input senders have completed. +\tcode{when_all} only accepts senders +with a single value completion signature and +on success concatenates all the input senders' value result datums +into its own value completion operation. +\tcode{when_all_with_variant(sndrs...)} is semantically equivalent to +w\tcode{hen_all(into_variant(sndrs)...)}, +where \tcode{sndrs} is a pack of subexpressions +whose types model \libconcept{sender}. + +\pnum +The names \tcode{when_all} and \tcode{when_all_with_variant} denote +customization point objects. +Let \tcode{sndrs} be a pack of subexpressions, +let \tcode{Sndrs} be a pack of the types \tcode{decltype((sndrs))...}, and +let \tcode{CD} be +the type \tcode{common_type_t}. +The expressions \tcode{when_all(sndrs...)} and +\tcode{when_all_with_variant(sndrs...)} are ill-formed +if any of the following is \tcode{true}: +\begin{itemize} +\item +\tcode{sizeof...(sndrs)} is \tcode{0}, or +\item +\tcode{(\libconcept{sender} \&\& ...)} is \tcode{false}, or +\item +\tcode{CD} is ill-formed. +\end{itemize} + +\pnum +The expression \tcode{when_all(sndrs...)} is expression-equivalent to: +\begin{codeblock} +transform_sender(CD(), @\exposid{make-sender}@(when_all, {}, sndrs...)) +\end{codeblock} + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \tcode{when_all_t} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-attrs}@ = @\seebelow@; + static constexpr auto @\exposid{get-env}@ = @\seebelow@; + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{start}@ = @\seebelow@; + static constexpr auto @\exposid{complete}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-attrs}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[](auto&&, auto&&... child) noexcept { + if constexpr (@\libconcept{same_as}@) { + return env<>(); + } else { + return @\exposid{MAKE-ENV}@(get_domain, CD()); + } +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-env}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[](auto&&, State& state, const Receiver& rcvr) noexcept { + return @\seebelow@; +} +\end{codeblock} +Returns an object \tcode{e} such that +\begin{itemize} +\item +\tcode{decltype(e)} models \exposconcept{queryable}, and +\item +\tcode{e.query(get_stop_token)} is expression-equivalent to +\tcode{state.\exposid{stop-src}.get_token()}, and +\item +given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t}, +\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}. +\end{itemize} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@$e$@) -> decltype(@$e$@) { + return @$e$@; +} +\end{codeblock} +where $e$ is the expression +\begin{codeblock} +std::forward(sndr).apply(@\exposid{make-state}@()) +\end{codeblock} +and where \exposid{make-state} is the following exposition-only class template: +\begin{codeblock} +template +concept @\defexposconcept{max-1-sender-in}@ = @\libconcept{sender_in}@ && // \expos + (tuple_size_v> <= 1); + +enum class @\exposid{disposition}@ { @\exposid{started}@, @\exposid{error}@, @\exposid{stopped}@ }; // \expos + +template +struct @\exposid{make-state}@ { + template<@\exposconcept{max-1-sender-in}@>... Sndrs> + auto operator()(auto, auto, Sndrs&&... sndrs) const { + using values_tuple = @\seebelow@; + using errors_variant = @\seebelow@; + using stop_callback = stop_callback_for_t>, @\exposid{on-stop-request}@>; + + struct @\exposid{state-type}@ { + void @\exposid{arrive}@(Rcvr& rcvr) noexcept { // \expos + if (0 == --count) { + @\exposid{complete}@(rcvr); + } + } + + void @\exposid{complete}@(Rcvr& rcvr) noexcept; // \expos + + atomic @\exposid{count}@{sizeof...(sndrs)}; // \expos + inplace_stop_source @\exposid{stop_src}@{}; // \expos + atomic<@\exposid{disposition}@> disp{@\exposidnc{disposition}@::@\exposidnc{started}@}; // \expos + errors_variant @\exposid{errors}@{}; // \expos + values_tuple @\exposid{values}@{}; // \expos + optional @\exposid{on_stop}@{nullopt}; // \expos + }; + + return @\exposid{state-type}@{}; + } +}; +\end{codeblock} + +\pnum +Let \exposid{copy-fail} be \tcode{exception_ptr} +if decay-copying any of the child senders' result datums can potentially throw; +otherwise, \exposid{none-such}, +where \exposid{none-such} is an unspecified empty class type. + +\pnum +The alias \tcode{values_tuple} denotes the type +\begin{codeblock} +tuple, @\exposid{decayed-tuple}@, optional>...> +\end{codeblock} +if that type is well-formed; otherwise, \tcode{tuple<>}. + +\pnum +The alias \tcode{errors_variant} denotes +the type \tcode{variant<\exposid{none-such}, \exposid{copy-fail}, Es...>} +with duplicate types removed, +where \tcode{Es} is the pack of the decayed types +of all the child senders' possible error result datums. + +\pnum +The member +\tcode{void \exposid{state-type}::\exposid{complete}(Rcvr\& rcvr) noexcept} +behaves as follows: +\begin{itemize} +\item +If \tcode{disp} is equal to \tcode{\exposid{disposition}::\exposid{started}}, +evaluates: +\begin{codeblock} +auto tie = [](tuple& t) noexcept { return tuple(t); }; +auto set = [&](auto&... t) noexcept { set_value(std::move(rcvr), std::move(t)...); }; + +@\exposid{on_stop}@.reset(); +apply( + [&](auto&... opts) noexcept { + apply(set, tuple_cat(tie(*opts)...)); + }, + values); +\end{codeblock} +\item +Otherwise, +if \tcode{disp} is equal to \tcode{\exposid{disposition}::\exposid{error}}, +evaluates: +\begin{codeblock} +@\exposid{on_stop}@.reset(); +visit( + [&](Error& error) noexcept { + if constexpr (!@\libconcept{same_as}@) { + set_error(std::move(rcvr), std::move(error)); + } + }, + errors); +\end{codeblock} +\item +Otherwise, evaluates: +\begin{codeblock} +@\exposid{on_stop}@.reset(); +set_stopped(std::move(rcvr)); +\end{codeblock} +\end{itemize} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[]( + State& state, Rcvr& rcvr, Ops&... ops) noexcept -> void { + state.@\exposid{on_stop}@.emplace( + get_stop_token(get_env(rcvr)), + @\exposid{on-stop-request}@{state.@\exposid{stop_src}@}); + if (state.@\exposid{stop_src}@.stop_requested()) { + state.@\exposid{on_stop.}@reset(); + set_stopped(std::move(rcvr)); + } else { + (start(ops), ...); + } +} +\end{codeblock} + +\pnum +The member \exposid{\tcode{impls-for}::\exposid{complete}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[]( + this auto& complete, Index, State& state, Rcvr& rcvr, Set, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@) { + if (@\exposid{disposition}@::@\exposid{error}@ != state.disp.exchange(@\exposid{disposition}@::@\exposid{error}@)) { + state.@\exposid{stop_src}@.request_stop(); + @\exposid{TRY-EMPLACE-ERROR}@(state.errors, std::forward(args)...); + } + } else if constexpr (@\libconcept{same_as}@) { + auto expected = @\exposid{disposition}@::@\exposid{started}@; + if (state.disp.compare_exchange_strong(expected, @\exposid{disposition}@::@\exposid{stopped}@)) { + state.@\exposid{stop_src}@.request_stop(); + } + } else if constexpr (!@\libconcept{same_as}@>) { + if (state.disp == @\exposid{disposition}@::@\exposid{started}@) { + auto& opt = get(state.values); + @\exposid{TRY-EMPLACE-VALUE}@(complete, opt, std::forward(args)...); + } + } + state.@\exposid{arrive}@(rcvr); +} +\end{codeblock} +where \tcode{\exposid{TRY-EMPLACE-ERROR}(v, e)}, +for subexpressions \tcode{v} and \tcode{e}, is equivalent to: +\begin{codeblock} +try { + v.template emplace(e); +} catch (...) { + v.template emplace(current_exception()); +} +\end{codeblock} +if the expression \tcode{decltype(auto(e))(e)} is potentially throwing; +otherwise, \tcode{v.template emplace(e)}; +and where \tcode{\exposid{TRY-EMPLACE-VALUE}(c, o, as...)}, +for subexpressions \tcode{c}, \tcode{o}, and pack of subexpressions \tcode{as}, +is equivalent to: +\begin{codeblock} +try { + o.emplace(as...); +} catch (...) { + c(Index(), state, rcvr, set_error, current_exception()); + return; +} +\end{codeblock} +if the expression \tcode{\exposid{decayed-tuple}\{as...\}} +is potentially throwing; +otherwise, \tcode{o.emplace(\linebreak as...)}. + +\pnum +The expression \tcode{when_all_with_variant(sndrs...)} +is expression-equivalent to: +\begin{codeblock} +transform_sender(CD(), @\exposid{make-sender}@(when_all_with_variant, {}, sndrs...)); +\end{codeblock} + +\pnum +Given subexpressions \tcode{sndr} and \tcode{env}, +if +\tcode{\exposconcept{sender-for}} +is \tcode{false}, +then the expression \tcode{when_all_with_variant.transform_sender(sndr, env)} +is ill-formed; +otherwise, it is equivalent to: +\begin{codeblock} +auto&& [_, _, ...child] = sndr; +return when_all(into_variant(std::forward_like(child))...); +\end{codeblock} +\begin{note} +This causes the \tcode{when_all_with_variant(sndrs...)} sender +to become \tcode{when_all(into_variant(sndrs)...)} +when it is connected with a receiver +whose execution domain does not customize \tcode{when_all_with_variant}. +\end{note} + +\rSec3[exec.into.variant]{\tcode{execution::into_variant}} + +\pnum +\tcode{into_variant} adapts a sender with multiple value completion signatures +into a sender with just one value completion signature +consisting of a \tcode{variant} of \tcode{tuple}s. + +\pnum +The name \tcode{into_variant} denotes a pipeable sender adaptor object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{Sndr} does not satisfy \libconcept{sender}, +\tcode{into_variant(sndr)} is ill-formed. + +\pnum +Otherwise, the expression \tcode{into_variant(sndr)} +is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(into_variant, {}, sndr)) +\end{codeblock} +except that \tcode{sndr} is only evaluated once. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +is specialized for \tcode{into_variant} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{complete}@ = @\seebelow@; + }; +} +\end{codeblock} + +\pnum +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 + -> type_identity, env_of_t>> { + return {}; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[]( + auto, State, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@) { + using variant_type = typename State::type; + @\exposid{TRY-SET-VALUE}@(rcvr, variant_type(@\exposid{decayed-tuple}@{std::forward(args)...})); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } +} +\end{codeblock} + +\rSec3[exec.stopped.opt]{\tcode{execution::stopped_as_optional}} + +\pnum +\tcode{stopped_as_optional} maps a sender's stopped completion operation +into a value completion operation as a disengaged \tcode{optional}. +The sender's value completion operation +is also converted into an \tcode{optional}. +The result is a sender that never completes with stopped, +reporting cancellation by completing with a disengaged \tcode{optional}. + +\pnum +The name \tcode{stopped_as_optional} denotes a pipeable sender adaptor object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +The expression \tcode{stopped_as_optional(sndr)} is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(stopped_as_optional, {}, sndr)) +\end{codeblock} +except that \tcode{sndr} is only evaluated once. + +\pnum +Let \tcode{sndr} and \tcode{env} be subexpressions +such that \tcode{Sndr} is \tcode{decltype((sndr))} and +\tcode{Env} is \tcode{decltype((env))}. +If \tcode{\exposconcept{sender-for}} +is \tcode{false}, or +if the type \tcode{\exposid{single-sender-value-type}} +is ill-formed or \tcode{void}, +then the expression \tcode{stopped_as_optional.transform_sender(sndr, env)} +is ill-formed; +otherwise, it is equivalent to: +\begin{codeblock} +auto&& [_, _, child] = sndr; +using V = @\exposid{single-sender-value-type}@; +return let_stopped( + then(std::forward_like(child), + [](Ts&&... ts) noexcept(is_nothrow_constructible_v) { + return optional(in_place, std::forward(ts)...); + }), + []() noexcept { return just(optional()); }); +\end{codeblock} + +\rSec3[exec.stopped.err]{\tcode{execution::stopped_as_error}} + +\pnum +\tcode{stopped_as_error} maps an input sender's stopped completion operation +into an error completion operation as a custom error type. +The result is a sender that never completes with stopped, +reporting cancellation by completing with an error. + +\pnum +The name \tcode{stopped_as_error} denotes a pipeable sender adaptor object. +For some subexpressions \tcode{sndr} and \tcode{err}, +let \tcode{Sndr} be \tcode{decltype((sndr))} and +let \tcode{Err} be \tcode{decltype((err))}. +If the type \tcode{Sndr} does not satisfy \libconcept{sender} or +if the type \tcode{Err} does not satisfy \exposconcept{movable-value}, +\tcode{stopped_as_error(sndr, err)} is ill-formed. +Otherwise, the expression \tcode{stopped_as_error(sndr, err)} +is expression-equivalent to: +\begin{codeblock} +transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(stopped_as_error, err, sndr)) +\end{codeblock} +except that \tcode{sndr} is only evaluated once. + +\pnum +Let \tcode{sndr} and \tcode{env} be subexpressions +such that \tcode{Sndr} is \tcode{decltype((sndr))} and +\tcode{Env} is \tcode{decltype((env))}. +If \tcode{\exposconcept{sender-for}} is \tcode{false}, +then the expression \tcode{stopped_as_error.transform_sender(sndr, env)} +is ill-formed; +otherwise, it is equivalent to: +\begin{codeblock} +auto&& [_, err, child] = sndr; +using E = decltype(auto(err)); +return let_stopped( + std::forward_like(child), + [err = std::forward_like(err)]() mutable noexcept(is_nothrow_move_constructible_v) { + return just_error(std::move(err)); + }); +\end{codeblock} + +\rSec2[exec.consumers]{Sender consumers} + +\rSec3[exec.sync.wait]{\tcode{this_thread::sync_wait}} + +\pnum +\tcode{this_thread::sync_wait} and \tcode{this_thread::sync_wait_with_variant} +are used +to block the current thread of execution +until the specified sender completes and +to return its async result. +\tcode{sync_wait} mandates +that the input sender has exactly one value completion signature. + +\pnum +Let \exposid{sync-wait-env} be the following exposition-only class type: +\begin{codeblock} +namespace std::this_thread { + struct @\exposid{sync-wait-env}@ { + execution::run_loop* @\exposid{loop}@; // \expos + + auto query(execution::get_scheduler_t) const noexcept { + return @\exposid{loop}@->get_scheduler(); + } + + auto query(execution::get_delegation_scheduler_t) const noexcept { + return @\exposid{loop}@->get_scheduler(); + } + }; +} +\end{codeblock} + +\pnum +Let \exposid{sync-wait-result-type} and +\exposid{sync-wait-with-variant-result-type} +be exposition-only alias templates defined as follows: +\begin{codeblock} +namespace std::this_thread { + template Sndr> + using @\exposid{sync-wait-result-type}@ = + optional>; + + template Sndr> + using @\exposid{sync-wait-with-variant-result-type}@ = + optional>; +} +\end{codeblock} + +\pnum +The name \tcode{this_thread::sync_wait} denotes a customization point object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{\libconcept{sender_in}} +is \tcode{false}, +the expression \tcode{this_thread::sync_wait(sndr)} is ill-formed. +Otherwise, it is expression-equivalent to the following, +except that \tcode{sndr} is evaluated only once: +\begin{codeblock} +apply_sender(@\exposid{get-domain-early}@(sndr), sync_wait, sndr) +\end{codeblock} +\mandates +\begin{itemize} +\item +The type \tcode{\exposid{sync-wait-result-type}} is well-formed. +\item +\tcode{\libconcept{same_as}>} +is \tcode{true}, where $e$ is the \tcode{apply_sender} expression above. +\end{itemize} + +\pnum +Let \exposid{sync-wait-state} and \exposid{sync-wait-receiver} +be the following exposition-only class templates: +\begin{codeblock} +namespace std::this_thread { + template + struct @\exposid{sync-wait-state}@ { // \expos + execution::run_loop @\exposid{loop}@; // \expos + exception_ptr @\exposid{error}@; // \expos + @\exposid{sync-wait-result-type}@ @\exposidnc{result}@; // \expos + }; + + template + struct @\exposid{sync-wait-receiver}@ { // \expos + using receiver_concept = execution::receiver_t; + @\exposidnc{sync-wait-state}@* @\exposid{state}@; // \expos + + template + void set_value(Args&&... args) && noexcept; + + template + void set_error(Error&& err) && noexcept; + + void set_stopped() && noexcept; + + @\exposid{sync-wait-env}@ get_env() const noexcept { return {&@\exposid{state}@->@\exposid{loop}@}; } + }; +} +\end{codeblock} + +\begin{itemdecl} +template +void set_value(Args&&... args) && noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +try { + @\exposid{state}@->@\exposid{result}@.emplace(std::forward(args)...); +} catch (...) { + @\exposid{state}@->@\exposid{error}@ = current_exception(); +} +@\exposid{state}@->@\exposid{loop}@.finish(); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template +void set_error(Error&& err) && noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{state}@->@\exposid{error}@ = @\exposid{AS-EXCEPT-PTR}@(std::forward(err)); // see \ref{exec.general} +@\exposid{state}@->@\exposid{loop}@.finish(); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +void set_stopped() && noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{\exposid{state}->\exposid{loop}.finish()}. +\end{itemdescr} + +\pnum +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{\libconcept{sender_to}>} +is \tcode{false}, +the expression \tcode{sync_wait.apply_sender(sndr)} is ill-formed; +otherwise, it is equivalent to: +\begin{codeblock} +@\exposid{sync-wait-state}@ state; +auto op = connect(sndr, @\exposid{sync-wait-receiver}@{&state}); +start(op); + +state.@\exposid{loop}@.run(); +if (state.@\exposid{error}@) { + rethrow_exception(std::move(state.@\exposid{error}@)); +} +return std::move(state.@\exposid{result}@); +\end{codeblock} + +\pnum +The behavior of \tcode{this_thread::sync_wait(sndr)} is undefined unless: +\begin{itemize} +\item +It blocks the current thread of execution\iref{defns.block} +with forward progress guarantee delegation\iref{intro.progress} +until the specified sender completes. +\begin{note} +The default implementation of \tcode{sync_wait} achieves +forward progress guarantee delegation by providing a \tcode{run_loop} scheduler +via the \tcode{get_delegation_scheduler} query +on the \exposid{sync-wait-receiver}'s environment. +The \tcode{run_loop} is driven by the current thread of execution. +\end{note} +\item +It returns the specified sender's async results as follows: +\begin{itemize} +\item +For a value completion, +the result datums are returned in +a \tcode{tuple} in an engaged \tcode{optional} object. +\item +For an error completion, an exception is thrown. +\item +For a stopped completion, a disengaged \tcode{optional} object is returned. +\end{itemize} +\end{itemize} + +\rSec3[exec.sync.wait.var]{\tcode{this_thread::sync_wait_with_variant}} + +\pnum +The name \tcode{this_thread::sync_wait_with_variant} denotes +a customization point object. +For a subexpression \tcode{sndr}, +let \tcode{Sndr} be \tcode{decltype(into_variant(sndr))}. +If \tcode{\libconcept{sender_in}} +is \tcode{false}, +\tcode{this_thread::sync_wait_with_variant(sndr)} is ill-formed. +Otherwise, it is expression-equivalent to the following, +except \tcode{sndr} is evaluated only once: +\begin{codeblock} +apply_sender(@\exposid{get-domain-early}@(sndr), sync_wait_with_variant, sndr) +\end{codeblock} +\mandates +\begin{itemize} +\item +The type \tcode{\exposid{sync-wait-with-variant-result-type}} +is well-formed. +\item +\tcode{\libconcept{same_as}>} +is \tcode{true}, where $e$ is the \tcode{ap\-ply_sender} expression above. +\end{itemize} + +\pnum +If \tcode{\exposconcept{callable}} is \tcode{false}, +the expression \tcode{sync_wait_with_variant.apply_sender(\linebreak sndr)} is ill-formed. +Otherwise, it is equivalent to: +\begin{codeblock} +using result_type = @\exposid{sync-wait-with-variant-result-type}@; +if (auto opt_value = sync_wait(into_variant(sndr))) { + return result_type(std::move(get<0>(*opt_value))); +} +return result_type(nullopt); +\end{codeblock} + +\pnum +The behavior of \tcode{this_thread::sync_wait_with_variant(sndr)} +is undefined unless: +\begin{itemize} +\item +It blocks the current thread of execution\iref{defns.block} +with forward progress guarantee delegation\iref{intro.progress} +until the specified sender completes. +\begin{note} +The default implementation of \tcode{sync_wait_with_variant} achieves +forward progress guarantee delegation by relying on +the forward progress guarantee delegation provided by \tcode{sync_wait}. +\end{note} +\item +It returns the specified sender's async results as follows: +\begin{itemize} +\item +For a value completion, +the result datums are returned in an engaged \tcode{optional} object +that contains a \tcode{variant} of \tcode{tuple}s. +\item +For an error completion, an exception is thrown. +\item +For a stopped completion, a disengaged \tcode{optional} object is returned. +\end{itemize} +\end{itemize} + +\rSec1[exec.util]{Sender/receiver utilities} + +\rSec2[exec.util.cmplsig]{\tcode{execution::completion_signatures}} + +\pnum +\tcode{completion_signatures} is a type +that encodes a set of completion signatures\iref{exec.async.ops}. + +\pnum +\begin{example} +\begin{codeblock} +struct my_sender { + using sender_concept = sender_t; + using completion_signatures = + execution::completion_signatures< + set_value_t(), + set_value_t(int, float), + set_error_t(exception_ptr), + set_error_t(error_code), + set_stopped_t()>; +}; +\end{codeblock} +Declares \tcode{my_sender} to be a sender +that can complete by calling one of the following +for a receiver expression \tcode{rcvr}: +\begin{itemize} +\item \tcode{set_value(rcvr)} +\item \tcode{set_value(rcvr, int\{...\}, float\{...\})} +\item \tcode{set_error(rcvr, exception_ptr\{...\})} +\item \tcode{set_error(rcvr, error_code\{...\})} +\item \tcode{set_stopped(rcvr)} +\end{itemize} +\end{example} + +\pnum +This subclause makes use of the following exposition-only entities: +\begin{codeblock} +template + concept @\defexposconcept{completion-signature}@ = @\seebelow@; +\end{codeblock} + +\pnum +A type \tcode{Fn} satisfies \exposconcept{completion-signature} +if and only if it is a function type with one of the following forms: +\begin{itemize} +\item +\tcode{set_value_t(Vs...)}, +where \tcode{Vs} is a pack of object or reference types. +\item +\tcode{set_error_t(Err)}, +where \tcode{Err} is an object or reference type. +\item +\tcode{set_stopped_t()} +\end{itemize} + +\pnum +\begin{codeblock} +template + struct @\exposid{indirect-meta-apply}@ { + template class T, class... As> + using @\exposid{meta-apply}@ = T; // \expos + }; + +template + concept @\defexposconcept{always-true}@ = true; // \expos + +template class Tuple, + template class Variant> + using @\exposid{gather-signatures}@ = @\seebelow@; +\end{codeblock} + +\pnum +Let \tcode{Fns} be a pack of the arguments of +the \tcode{completion_signatures} specialization named by \tcode{Completions}, +let \tcode{TagFns} be a pack of the function types in \tcode{Fns} +whose return types are \tcode{Tag}, and +let $\tcode{Ts}_n$ be a pack of the function argument types +in the $n$-th type in \tcode{TagFns}. +Then, given two variadic templates \tcode{Tuple} and \tcode{Variant}, +the type \tcode{\exposid{gather-signatures}} +names the type +\begin{codeblock} +@\exposid{META-APPLY}@(Variant, @\exposid{META-APPLY}@(Tuple, Ts@$_0$@...), + @\itcorr[1]\exposid{META-APPLY}@(Tuple, Ts@$_1$@...), + @\itcorr[1]\ldots@, + @\itcorr[1]\exposid{META-APPLY}@(Tuple, Ts@$_{m-1}$@...)) +\end{codeblock} +where $m$ is the size of the pack \tcode{TagFns} and +\tcode{META-APPLY(T, As...)} is equivalent to: +\begin{codeblock} +typename @\exposid{indirect-meta-apply}@<@\exposid{always-true}@>::template @\exposid{meta-apply}@ +\end{codeblock} + +\pnum +\begin{note} +The purpose of \exposid{META-APPLY} is to make it valid +to use non-variadic templates as \tcode{Variant} and \tcode{Tuple} arguments +to \exposid{gather-signatures}. +\end{note} + +\pnum +\begin{codeblock} +namespace std::execution { + template<@\exposconcept{completion-signature}@... Fns> + struct completion_signatures {}; + + template, + template class Tuple = @\exposid{decayed-tuple}@, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using value_types_of_t = + @\exposid{gather-signatures}@, Tuple, Variant>; + + template, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using error_types_of_t = + @\exposid{gather-signatures}@, + type_identity_t, Variant>; + + template> + requires @\libconcept{sender_in}@ + constexpr bool sends_stopped = + !@\libconcept{same_as}@<@\exposid{type-list}@<>, + @\exposid{gather-signatures}@, + @\exposid{type-list}@, @\exposid{type-list}@>>; +} +\end{codeblock} + +\rSec2[exec.util.cmplsig.trans]{\tcode{execution::transform_completion_signatures}} + +\pnum +\tcode{transform_completion_signatures} is an alias template +used to transform one set of completion signatures into another. +It takes a set of completion signatures and +several other template arguments +that apply modifications to each completion signature in the set +to generate a new specialization of \tcode{completion_signature}s. +\pnum +\begin{example} +Given a sender \tcode{Sndr} and an environment \tcode{Env}, +adapt the completion signatures of \tcode{Sndr} by +lvalue-ref qualifying the values, +adding an additional \tcode{exception_ptr} error completion +if it is not already there, and +leaving the other completion signatures alone. +\begin{codeblock} +template + using my_set_value_t = + completion_signatures< + set_value_t(add_lvalue_reference_t...)>; + +using my_completion_signatures = + transform_completion_signatures< + completion_signatures_of_t, + completion_signatures, + my_set_value_t>; +\end{codeblock} +\end{example} + +\pnum +This subclause makes use of the following exposition-only entities: +\begin{codeblock} +template + using @\exposid{default-set-value}@ = + completion_signatures; + +template + using @\exposid{default-set-error}@ = + completion_signatures; +\end{codeblock} + +\pnum +\begin{codeblock} +namespace std::execution { + template<@\exposconcept{valid-completion-signatures}@ InputSignatures, + @\exposconcept{valid-completion-signatures}@ AdditionalSignatures = completion_signatures<>, + template class SetValue = @\exposid{default-set-value}@, + template class SetError = @\exposid{default-set-error}@, + @\exposconcept{valid-completion-signatures}@ SetStopped = completion_signatures> + using transform_completion_signatures = completion_signatures<@\seebelow@>; +} +\end{codeblock} + +\pnum +\tcode{SetValue} shall name an alias template +such that for any pack of types \tcode{As}, +the type \tcode{SetValue} is either ill-formed or else +\tcode{\exposconcept{valid-completion-signatures}>} is satisfied. +\tcode{SetError} shall name an alias template +such that for any type \tcode{Err}, +\tcode{SetError} is either ill-formed or else +\tcode{\exposconcept{valid-completion-signatures}>} is satisfied. + +\pnum +Let \tcode{Vs} be a pack of the types in the \exposid{type-list} named by +\tcode{\exposid{gather-signatures}}. + +\pnum +Let \tcode{Es} be a pack of the types in the \exposid{type-list} named by +\tcode{\exposid{gather-signatures}}, +where \exposid{error-list} is an alias template +such that \tcode{\exposid{error-list}<\linebreak Ts...>} is +\tcode{\exposid{type-list}...>}. + +\pnum +Let \tcode{Ss} name the type \tcode{completion_signatures<>} if +\tcode{\exposid{gather-signatures}} +is an alias for the type \tcode{\exposid{type-list}<>}; +otherwise, \tcode{SetStopped}. + +\pnum +If any of the above types are ill-formed, +then +\begin{codeblock} +transform_completion_signatures +\end{codeblock} +is ill-formed. +Otherwise, +\begin{codeblock} +transform_completion_signatures +\end{codeblock} +is the type \tcode{completion_signatures} +where \tcode{Sigs...} is the unique set of types in all the template arguments +of all the \tcode{completion_signatures} specializations in the set +\tcode{AdditionalSignatures}, \tcode{Vs...}, \tcode{Es...}, \tcode{Ss}. + +\rSec1[exec.envs]{Queryable utilities} + +\rSec2[exec.prop]{Class template \tcode{prop}} + +\begin{codeblock} +namespace std::execution { + template + struct @\libglobal{prop}@ { + QueryTag @\exposid{query_}@; // \expos + ValueType @\exposid{value_}@; // \expos + + constexpr const ValueType& query(QueryTag) const noexcept { + return @\exposid{value_}@; + } + }; + + template + prop(QueryTag, ValueType) -> prop>; +} +\end{codeblock} + +\pnum +Class template \tcode{prop} is for building a queryable object +from a query object and a value. + +\pnum +\mandates +\tcode{\exposconcept{callable}>} +is modeled, +where \exposid{prop-like} is the following exposition-only class template: +\begin{codeblock} +template +struct @\exposid{prop-like}@ { // \expos + const ValueType& query(auto) const noexcept; +}; +\end{codeblock} + +\pnum +\begin{example} +\begin{codeblock} +template<@\libconcept{sender}@ Sndr> +sender auto parameterize_work(Sndr sndr) { + // Make an environment such that \tcode{get_allocator(env)} returns a reference to a copy of \tcode{my_alloc\{\}}. + auto e = prop(get_allocator, my_alloc{}); + + // Parameterize the input sender so that it will use our custom execution environment. + return write_env(sndr, e); +} +\end{codeblock} +\end{example} + +\pnum +Specializations of \tcode{prop} are not assignable. + +\rSec2[exec.env]{Class template \tcode{env}} + +\begin{codeblock} +namespace std::execution { + template<@\exposconcept{queryable}@... Envs> + struct @\libglobal{env}@ { + Envs@$_0$@ @$\exposid{envs}_0$@; // \expos + Envs@$_1$@ @$\exposid{envs}_1$@; // \expos + @\vdots@ + Envs@$_{n-1}$@ @$\exposid{envs}_{n-1}$@; // \expos + + template + constexpr decltype(auto) query(QueryTag q) const noexcept(@\seebelow@); + }; + + template + env(Envs...) -> env...>; +} +\end{codeblock} + +\pnum +The class template \tcode{env} is used to construct a queryable object +from several queryable objects. +Query invocations on the resulting object are resolved +by attempting to query each subobject in lexical order. + +\pnum +Specializations of \tcode{env} are not assignable. + +\pnum +It is unspecified +whether \tcode{env} supports initialization +using a parenthesized \grammarterm{expression-list}\iref{dcl.init}, +unless the \grammarterm{expression-list} consist of +a single element of type (possibly const) \tcode{env}. + +\pnum +\begin{example} +\begin{codeblock} +template<@\libconcept{sender}@ Sndr> +sender auto parameterize_work(Sndr sndr) { + // Make an environment such that: + // \tcode{get_allocator(env)} returns a reference to a copy of \tcode{my_alloc\{\}} + // \tcode{get_scheduler(env)} returns a reference to a copy of \tcode{my_sched\{\}} + auto e = env{prop(get_allocator, my_alloc{}), + prop(get_scheduler, my_sched{})}; + + // Parameterize the input sender so that it will use our custom execution environment. + return write_env(sndr, e); +} +\end{codeblock} +\end{example} + +\indexlibrarymember{query}{env}% +\begin{itemdecl} +template +constexpr decltype(auto) query(QueryTag q) const noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \exposconcept{has-query} be the following exposition-only concept: +\begin{codeblock} +template + concept @\defexposconcept{has-query}@ = // \expos + requires (const Env& env) { + env.query(QueryTag()); + }; +\end{codeblock} + +\pnum +Let \exposid{fe} be the first element of +$\exposid{envs}_0$, $\exposid{envs}_1$, $\dotsc$, $\exposid{envs}_{n-1}$ +such that the expression \tcode{\exposid{fe}.query(q)} is well-formed. + +\pnum +\constraints +\tcode{(\exposconcept{has-query} || ...)} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return \exposid{fe}.query(q);} + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is equivalent +to \tcode{noexcept(\exposid{fe}.query(q))}. +\end{itemdescr} + +\rSec1[exec.ctx]{Execution contexts} + +\rSec2[exec.run.loop]{\tcode{execution::run_loop}} + +\rSec3[exec.run.loop.general]{General} + +\pnum +A \tcode{run_loop} is an execution resource on which work can be scheduled. +It maintains a thread-safe first-in-first-out queue of work. +Its \tcode{run} member function removes elements from the queue and +executes them in a loop on the thread of execution that calls \tcode{run}. + +\pnum +A \tcode{run_loop} instance has an associated \defn{count} +that corresponds to the number of work items that are in its queue. +Additionally, a \tcode{run_loop} instance has an associated state +that can be one of +\defn{starting}, \defn{running}, \defn{finishing}, or \defn{finished}. + +\pnum +Concurrent invocations of the member functions of \tcode{run_loop} +other than \tcode{run} and its destructor do not introduce data races. +The member functions +\exposid{pop-front}, \exposid{push-back}, and \tcode{finish} +execute atomically. + +\pnum +\recommended +Implementations should use an intrusive queue of operation states +to hold the work units to make scheduling allocation-free. + +\begin{codeblock} +namespace std::execution { + class @\libglobal{run_loop}@ { + // \ref{exec.run.loop.types}, associated types + class @\exposid{run-loop-scheduler}@; // \expos + class @\exposid{run-loop-sender}@; // \expos + struct @\exposid{run-loop-opstate-base}@ { // \expos + virtual void @\exposid{execute}@() = 0; // \expos + run_loop* @\exposid{loop}@; // \expos + @\exposid{run-loop-opstate-base}@* @\exposid{next}@; // \expos + }; + template + using @\exposid{run-loop-opstate}@ = @\unspec@; // \expos + + // \ref{exec.run.loop.members}, member functions + @\exposid{run-loop-opstate-base}@* @\exposid{pop-front}@(); // \expos + void @\exposid{push-back}@(@\exposid{run-loop-opstate-base}@*); // \expos + + public: + // \ref{exec.run.loop.ctor}, constructor and destructor + run_loop() noexcept; + run_loop(run_loop&&) = delete; + ~run_loop(); + + // \ref{exec.run.loop.members}, member functions + @\exposid{run-loop-scheduler}@ get_scheduler(); + void run(); + void finish(); + }; +} +\end{codeblock} + +\rSec3[exec.run.loop.types]{Associated types} + +\begin{itemdecl} +class @\exposid{run-loop-scheduler}@; +\end{itemdecl} + +\pnum +\exposid{run-loop-scheduler} is an unspecified type +that models \libconcept{scheduler}. + +\pnum +Instances of \exposid{run-loop-scheduler} remain valid +until the end of the lifetime of the \tcode{run_loop} instance +from which they were obtained. + +\pnum +Two instances of \exposid{run-loop-scheduler} compare equal +if and only if they were obtained from the same \tcode{run_loop} instance. + +\pnum +Let \exposid{sch} be an expression of type \exposid{run-loop-scheduler}. +The expression \tcode{schedule(\exposid{sch})} +has type \exposid{run-loop-\newline sender} and +is not potentially-throwing if \exposid{sch} is not potentially-throwing. + +\begin{itemdecl} +class @\exposid{run-loop-sender}@; +\end{itemdecl} + +\pnum +\exposid{run-loop-sender} is an exposition-only type +that satisfies \libconcept{sender}. +For any type \tcode{Env}, +\tcode{completion_signatures_of_t<\exposid{run-loop-sender}, Env>} is +\begin{codeblock} +completion_signatures +\end{codeblock} + +\pnum +An instance of \exposid{run-loop-sender} remains valid +until the end of the lifetime of its associated \tcode{run_loop} instance. + +\pnum +Let \exposid{sndr} be an expression of type \exposid{run-loop-sender}, +let \exposid{rcvr} be an expression +such that \tcode{\libconcept{receiver_of}} is \tcode{true} +where \tcode{CS} is the \tcode{completion_signatures} specialization above. +Let \tcode{C} be either \tcode{set_value_t} or \tcode{set_stopped_t}. +Then: +\begin{itemize} +\item +The expression \tcode{connect(\exposid{sndr}, \exposid{rcvr})} +has type \tcode{\exposid{run-loop-opstate}>} +and is potentially-throwing if and only if +\tcode{(void(\exposid{sndr}), auto(\exposid{rcvr}))} is potentially-throwing. +\item +The expression \tcode{get_completion_scheduler(get_env(\exposid{sndr}))} +is potentially-throwing if and only if \exposid{sndr} is potentially-throwing, +has type \exposid{run-loop-scheduler}, and +compares equal to the \exposid{run-loop-\newline scheduler} instance +from which \exposid{sndr} was obtained. +\end{itemize} + +\begin{itemdecl} +template + struct @\exposid{run-loop-opstate}@; +\end{itemdecl} + +\pnum +\tcode{\exposid{run-loop-opstate}} +inherits privately and unambiguously from \exposid{run-loop-opstate-base}. + +\pnum +Let $o$ be a non-const lvalue of type \tcode{\exposid{run-loop-opstate}}, +and let \tcode{REC($o$)} be a non-const lvalue reference to an instance of type \tcode{Rcvr} +that was initialized with the expression \exposid{rcvr} +passed to the invocation of connect that returned $o$. +Then: +\begin{itemize} +\item +The object to which \tcode{\exposid{REC}($o$)} refers +remains valid for the lifetime of the object to which $o$ refers. +\item +The type \tcode{\exposid{run-loop-opstate}} overrides +\tcode{\exposid{run-loop-opstate-base}::\exposid{execute}()} +such that \tcode{$o$.\exposid{exe\-cute}()} is equivalent to: +\begin{codeblock} +if (get_stop_token(@\exposid{REC}@(@$o$@)).stop_requested()) { + set_stopped(std::move(@\exposid{REC}@(@$o$@))); +} else { + set_value(std::move(@\exposid{REC}@(@$o$@))); +} +\end{codeblock} +\item +The expression \tcode{start($o$)} is equivalent to: +\begin{codeblock} +try { + @$o$@.@\exposid{loop}@->@\exposid{push-back}@(addressof(@$o$@)); +} catch(...) { + set_error(std::move(@\exposid{REC}@(@$o$@)), current_exception()); +} +\end{codeblock} +\end{itemize} + +\rSec3[exec.run.loop.ctor]{Constructor and destructor} + +\indexlibraryctor{run_loop}% +\begin{itemdecl} +run_loop() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\exposid{count} is \tcode{0} and \exposid{state} is \exposid{starting}. +\end{itemdescr} + +\indexlibrarydtor{run_loop}% +\begin{itemdecl} +~run_loop(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \exposid{count} is not \tcode{0} or if \exposid{state} is \exposid{running}, +invokes \tcode{terminate}\iref{except.terminate}. +Otherwise, has no effects. +\end{itemdescr} + +\rSec3[exec.run.loop.members]{Member functions} + +\begin{itemdecl} +@\exposid{run-loop-opstate-base}@* @\exposid{pop-front}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Blocks\iref{defns.block} until one of the following conditions is \tcode{true}: +\begin{itemize} +\item +\exposid{count} is \tcode{0} and \exposid{state} is \exposid{finishing}, +in which case \exposid{pop-front} sets \exposid{state} to \exposid{finished} +and returns \tcode{nullptr}; or +\item +\exposid{count} is greater than \tcode{0}, +in which case an item is removed from the front of the queue, +\exposid{count} is decremented by \tcode{1}, and +the removed item is returned. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +void @\exposid{push-back}@(@\exposid{run-loop-opstate-base}@* item); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds \tcode{item} to the back of the queue and +increments \exposid{count} by \tcode{1}. + +\pnum +\sync +This operation synchronizes with +the \exposid{pop-front} operation that obtains \tcode{item}. +\end{itemdescr} + +\indexlibrarymember{get_scheduler}{run_loop}% +\begin{itemdecl} +@\exposid{run-loop-scheduler}@ get_scheduler(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An instance of \exposid{run-loop-scheduler} +that can be used to schedule work onto this \tcode{run_loop} instance. +\end{itemdescr} + +\indexlibrarymember{run}{run_loop}% +\begin{itemdecl} +void run(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\exposid{state} is either \exposid{starting} or \exposid{finishing}. + +\pnum +\effects +If \exposid{state} is \exposid{starting}, +sets the \exposid{state} to \exposid{running}, +otherwise leaves \exposid{state} unchanged. +Then, equivalent to: +\begin{codeblock} +while (auto* op = @\exposid{pop-front}@()) { + op->@\exposid{execute}@(); +} +\end{codeblock} + +\pnum +\remarks +When \exposid{state} changes, it does so without introducing data races. +\end{itemdescr} + +\indexlibrarymember{finish}{run_loop}% +\begin{itemdecl} +void finish(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\exposid{state} is either \exposid{starting} or \exposid{running}. + +\pnum +\effects +Changes \exposid{state} to \exposid{finishing}. + +\pnum +\sync +\tcode{finish} synchronizes with the \exposid{pop-front} operation +that returns \tcode{nullptr}. +\end{itemdescr} + +\rSec1[exec.coro.util]{Coroutine utilities} + +\rSec2[exec.as.awaitable]{\tcode{execution::as_awaitable}} + +\pnum +\tcode{as_awaitable} transforms an object into one +that is awaitable within a particular coroutine. +Subclause \ref{exec.coro.util} makes use of +the following exposition-only entities: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{awaitable-sender}@ = + @\exposconcept{single-sender}@> && + @\libconcept{sender_to}@ && // \seebelow + requires (Promise& p) { + { p.unhandled_stopped() } -> @\libconcept{convertible_to}@>; + }; + + template + class @\exposidnc{sender-awaitable}@; // \expos +} +\end{codeblock} + +\pnum +The type \tcode{\exposid{sender-awaitable}} is equivalent to: + +\begin{codeblock} +namespace std::execution { + template + class @\exposidnc{sender-awaitable}@ { + struct @\exposidnc{unit}@ {}; // \expos + using @\exposidnc{value-type}@ = // \expos + @\exposidnc{single-sender-value-type}@>; + using @\exposidnc{result-type }@= // \expos + conditional_t, unit, @\exposid{value-type}@>; + struct @\exposidnc{awaitable-receiver}@; // \expos + + variant @\exposidnc{result}@{}; // \expos + connect_result_t @\exposidnc{state}@; // \expos + + public: + @\exposid{sender-awaitable}@(Sndr&& sndr, Promise& p); + static constexpr bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle) noexcept { start(@\exposid{state}@); } + @\exposid{value-type}@ await_resume(); + }; +} +\end{codeblock} + +\pnum +\exposid{awaitable-receiver} is equivalent to: +\begin{codeblock} +struct @\exposid{awaitable-receiver}@ { + using receiver_concept = receiver_t; + variant* @\exposidnc{result-ptr}@; // \expos + coroutine_handle @\exposidnc{continuation}@; // \expos + // \seebelow +}; +\end{codeblock} + +\pnum +Let \tcode{rcvr} be an rvalue expression of type \exposid{awaitable-receiver}, +let \tcode{crcvr} be a const lvalue that refers to \tcode{rcvr}, +let \tcode{vs} be a pack of subexpressions, and +let \tcode{err} be an expression of type \tcode{Err}. Then: +\begin{itemize} +\item +If \tcode{\libconcept{constructible_from}<\exposid{result-type}, decltype((vs))...>} +is satisfied, +the expression \tcode{set_value(\newline rcvr, vs...)} is equivalent to: +\begin{codeblock} +try { + rcvr.@\exposid{result-ptr}@->template emplace<1>(vs...); +} catch(...) { + rcvr.@\exposid{result-ptr}@->template emplace<2>(current_exception()); +} +rcvr.@\exposid{continuation}@.resume(); +\end{codeblock} +Otherwise, \tcode{set_value(rcvr, vs...)} is ill-formed. +\item +The expression \tcode{set_error(rcvr, err)} is equivalent to: +\begin{codeblock} +rcvr.@\exposid{result-ptr}@->template emplace<2>(@\exposid{AS-EXCEPT-PTR}@(err)); // see \ref{exec.general} +rcvr.@\exposid{continuation}@.resume(); +\end{codeblock} +\item +The expression \tcode{set_stopped(rcvr)} is equivalent to: +\begin{codeblock} +static_cast>(rcvr.@\exposid{continuation}@.promise().unhandled_stopped()).resume(); +\end{codeblock} +\item +For any expression \tcode{tag} +whose type satisfies \exposconcept{forwarding-query} and +for any pack of subexpressions \tcode{as}, +\tcode{get_env(crcvr).query(tag, as...)} is expression-equivalent to: +\begin{codeblock} +tag(get_env(as_const(crcvr.@\exposid{continuation}@.promise())), as...) +\end{codeblock} +\end{itemize} + +\begin{itemdecl} +@\exposid{sender-awaitable}@(Sndr&& sndr, Promise& p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{state} with +\begin{codeblock} +connect(std::forward(sndr), + @\exposid{awaitable-receiver}@{addressof(result), coroutine_handle::from_promise(p)}) +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +@\exposid{value-type}@ await_resume(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (@\exposid{result}@.index() == 2) + rethrow_exception(get<2>(@\exposid{result}@)); +if constexpr (!is_void_v<@\exposid{value-type}@>) + return std::forward<@\exposid{value-type}@>(get<1>(@\exposid{result}@)); +\end{codeblock} +\end{itemdescr} + +\pnum +\tcode{as_awaitable} is a customization point object. +For subexpressions \tcode{expr} and \tcode{p} +where \tcode{p} is an lvalue, +\tcode{Expr} names the type \tcode{decltype((expr))} and +\tcode{Promise} names the type \tcode{decay_t}, +\tcode{as_awaitable(expr, p)} is expression-equivalent to, +except that the evaluations of \tcode{expr} and \tcode{p} +are indeterminately sequenced: +\begin{itemize} +\item +\tcode{expr.as_awaitable(p)} if that expression is well-formed. + +\mandates +\tcode{\exposconcept{is-awaitable}} is \tcode{true}, +where \tcode{A} is the type of the expression above. +\item +Otherwise, \tcode{(void(p), expr)} +if \tcode{\exposconcept{is-awaitable}} is \tcode{true}, +where \tcode{U} is an unspecified class type +that is not \tcode{Promise} and +that lacks a member named \tcode{await_transform}. + +\expects +\tcode{\exposconcept{is-awaitable}} is \tcode{true} and +the expression \tcode{co_await expr} +in a coroutine with promise type \tcode{U} is expression-equivalent to +the same expression in a coroutine with promise type \tcode{Promise}. +\item +Otherwise, \tcode{\exposid{sender-awaitable}\{expr, p\}} +if \tcode{\exposconcept{awaitable-sender}} is \tcode{true}. +\item +Otherwise, \tcode{(void(p), expr)}. +\end{itemize} + +\rSec2[exec.with.awaitable.senders]{\tcode{execution::with_awaitable_senders}} + +\pnum +\tcode{with_awaitable_senders}, +when used as the base class of a coroutine promise type, +makes senders awaitable in that coroutine type. + +In addition, it provides a default implementation of \tcode{unhandled_stopped} +such that if a sender completes by calling \tcode{set_stopped}, +it is treated as if an uncatchable "stopped" exception were thrown +from the \grammarterm{await-expression}. +\begin{note} +The coroutine is never resumed, and +the \tcode{unhandled_stopped} of the coroutine caller's promise type is called. +\end{note} + +\begin{codeblock} +namespace std::execution { + template<@\exposconcept{class-type}@ Promise> + struct @\libglobal{with_awaitable_senders}@ { + template + requires (!@\libconcept{same_as}@) + void set_continuation(coroutine_handle h) noexcept; + + coroutine_handle<> @\libmember{continuation}{with_awaitable_senders}@() const noexcept { return @\exposid{continuation}@; } + + coroutine_handle<> @\libmember{unhandled_stopped}{with_awaitable_senders}@() noexcept { + return @\exposid{stopped-handler}@(@\exposid{continuation}@.address()); + } + + template + @\seebelow@ await_transform(Value&& value); + + private: + [[noreturn]] static coroutine_handle<> + @\exposid{default-unhandled-stopped}@(void*) noexcept { // \expos + terminate(); + } + coroutine_handle<> @\exposid{continuation}@{}; // \expos + coroutine_handle<> (*@\exposid{stopped-handler}@)(void*) noexcept = // \expos + &@\exposid{default-unhandled-stopped}@; + }; +} +\end{codeblock} + +\indexlibrarymember{set_continuation}{with_awaitable_senders}% +\begin{itemdecl} +template + requires (!@\libconcept{same_as}@) +void set_continuation(coroutine_handle h) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{continuation}@ = h; +if constexpr ( requires(OtherPromise& other) { other.unhandled_stopped(); } ) { + @\exposid{stopped-handler}@ = [](void* p) noexcept -> coroutine_handle<> { + return coroutine_handle::from_address(p) + .promise().unhandled_stopped(); + }; +} else { + @\exposid{stopped-handler}@ = &@\exposid{default-unhandled-stopped}@; +} +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{await_transform}{with_awaitable_senders}% +\begin{itemdecl} +template +@\exposid{call-result-t}@ await_transform(Value&& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return as_awaitable(std::forward(value), static_cast(*this)); +\end{codeblock} +\end{itemdescr} diff --git a/source/expressions.tex b/source/expressions.tex index 683b30137f..aed3d0b9dc 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -53,7 +53,7 @@ considered where necessary to convert the operands to types appropriate for the built-in operator. If a built-in operator is selected, such conversions will be applied to the operands before the operation is -considered further according to the rules in subclause \ref{expr.compound}; +considered further according to the rules in \ref{expr.compound}; see~\ref{over.match.oper}, \ref{over.built}. \pnum @@ -131,7 +131,7 @@ \begin{footnote} The cast and assignment operators must still perform their specific conversions as described in~\ref{expr.type.conv}, \ref{expr.cast}, -\ref{expr.static.cast} and~\ref{expr.ass}. +\ref{expr.static.cast} and~\ref{expr.assign}. \end{footnote} \rSec1[expr.prop]{Properties of expressions} @@ -233,13 +233,11 @@ A prvalue whose result is the value \placeholder{V} is sometimes said to have or name the value \placeholder{V}. The \defn{result object} of a prvalue is the object initialized by the prvalue; -a non-discarded prvalue -that is used to compute the value of an operand of a built-in operator -or a prvalue that has type \cv{}~\keyword{void} +a prvalue that has type \cv{}~\keyword{void} has no result object. \begin{note} Except when the prvalue is the operand of a \grammarterm{decltype-specifier}, -a prvalue of class or array type always has a result object. +a prvalue of object type always has a result object. For a discarded prvalue that has type other than \cv{}~\keyword{void}, a temporary object is materialized; see \ref{expr.context}. \end{note} @@ -266,9 +264,11 @@ \end{note} \pnum -Whenever a prvalue appears as an operand of an operator that -expects a glvalue for that operand, the -temporary materialization conversion\iref{conv.rval} is +Unless otherwise specified\iref{expr.reinterpret.cast, expr.const.cast}, +whenever a prvalue +that is not the result of the lvalue-to-rvalue conversion\iref{conv.lval} +appears as an operand of an operator, +the temporary materialization conversion\iref{conv.rval} is applied to convert the expression to an xvalue. \pnum @@ -296,7 +296,7 @@ \begin{note} A program that attempts to modify an object through a nonmodifiable lvalue or through an rvalue -is ill-formed\iref{expr.ass,expr.post.incr,expr.pre.incr}. +is ill-formed\iref{expr.assign,expr.post.incr,expr.pre.incr}. \end{note} \pnum @@ -321,7 +321,7 @@ If a program invokes a defaulted copy/move constructor or copy/move assignment operator for a union of type \tcode{U} with a glvalue argument -that does not denote an object of type \cv{}~\keyword{U} within its lifetime, +that does not denote an object of type \cv{}~\tcode{U} within its lifetime, the behavior is undefined. \begin{note} In C, an entire object of structure type can be accessed, e.g., using assignment. @@ -335,9 +335,13 @@ \indextext{expression!reference}% If an expression initially has the type ``reference to \tcode{T}''\iref{dcl.ref,dcl.init.ref}, the type is adjusted to -\tcode{T} prior to any further analysis. The expression designates the -object or function denoted by the reference, and the expression -is an lvalue or an xvalue, depending on the expression. +\tcode{T} prior to any further analysis; +the value category of the expression is not altered. +Let $X$ be the object or function denoted by the reference. +If a pointer to $X$ would be valid in +the context of the evaluation of the expression\iref{basic.fundamental}, +the result designates $X$; +otherwise, the behavior is undefined. \begin{note} Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see~\ref{basic.life}). @@ -433,7 +437,8 @@ \pnum \label{term.unevaluated.operand}% In some contexts, \defnx{unevaluated operands}{unevaluated operand} -appear\iref{expr.prim.req, +appear\iref{expr.prim.req.simple, +expr.prim.req.compound, expr.typeid, expr.sizeof, expr.unary.noexcept, @@ -622,7 +627,7 @@ prvalue is \tcode{T}. \begin{footnote} In \Cpp{} class and array prvalues can have cv-qualified types. -This differs from ISO C, in which non-lvalues never have +This differs from C, in which non-lvalues never have cv-qualified types. \end{footnote} @@ -670,14 +675,29 @@ the glvalue. \item Otherwise, if the object to which the glvalue refers contains an invalid -pointer value\iref{basic.stc.dynamic.deallocation}, the behavior is +pointer value\iref{basic.compound}, the behavior is \impldef{lvalue-to-rvalue conversion of an invalid pointer value}. -\item Otherwise, the object indicated by the glvalue is read\iref{defns.access}, -and the value contained in the object is the prvalue result. -If the result is an erroneous value\iref{basic.indet} and -the bits in the value representation are not valid for the object's type, -the behavior is undefined. +\item Otherwise, if the bits in the value representation of +the object to which the glvalue refers +are not valid for the object's type, the behavior is undefined. +\begin{example} +\begin{codeblock} +bool f() { + bool b = true; + char c = 42; + memcpy(&b, &c, 1); + return b; // undefined behavior if \tcode{42} is not a valid value representation for \keyword{bool} +} +\end{codeblock} +\end{example} + +\item Otherwise, the object indicated by the glvalue is read\iref{defns.access}. +Let \tcode{V} be the value contained in the object. +If \tcode{T} is an integer type, +the prvalue result is +the value of type \tcode{T} congruent\iref{basic.fundamental} to \tcode{V}, and +\tcode{V} otherwise. \end{itemize} \pnum @@ -1034,16 +1054,26 @@ The pointer value\iref{basic.compound} is unchanged by this conversion. \pnum -A prvalue of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} +A prvalue \tcode{v} of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} is a complete class type, can be converted to a prvalue of type ``pointer to \cv{} \tcode{B}'', where \tcode{B} is a base class\iref{class.derived} of \tcode{D}. If \tcode{B} is an inaccessible\iref{class.access} or ambiguous\iref{class.member.lookup} base class of \tcode{D}, a program -that necessitates this conversion is ill-formed. The result of the -conversion is a pointer to the base class subobject of the derived class -object. The null pointer value is converted to the null pointer value of -the destination type. +that necessitates this conversion is ill-formed. +If \tcode{v} is a null pointer value, +the result is a null pointer value. +Otherwise, +if \tcode{B} is a virtual base class of \tcode{D} and +\tcode{v} does not point to an object +whose type is similar\iref{conv.qual} to \tcode{D} and +that is +within its lifetime or +within its period of construction or destruction\iref{class.cdtor}, +the behavior is undefined. +Otherwise, +the result is a pointer to the base class subobject of +the derived class object. \rSec2[conv.mem]{Pointer-to-member conversions} @@ -1155,7 +1185,7 @@ the following rules are applied: \begin{itemize} \item -If both operands have the same type, no further conversion is needed. +If both operands have the same type, no further conversion is performed. \item Otherwise, if one of the operands is of a non-floating-point type, that operand is converted to the type of @@ -1207,6 +1237,8 @@ \rSec1[expr.prim]{Primary expressions}% \indextext{expression!primary|(} +\rSec2[expr.prim.grammar]{Grammar} + \begin{bnf} \nontermdef{primary-expression}\br literal\br @@ -1247,6 +1279,16 @@ A \grammarterm{lambda-expression} does not introduce a class scope. \end{note} +\pnum +If the expression \tcode{this} +appears within the predicate of a contract assertion\iref{basic.contract.general} +(including as the result of an implicit transformation\iref{expr.prim.id.general} +and including in the bodies of nested \grammarterm{lambda-expression}s) +and the current class +encloses the contract assertion, +\keyword{const} is combined with the \grammarterm{cv-qualifier-seq} +used to generate the resulting type (see below). + \pnum If a declaration declares a member function or member function template of a class \tcode{X}, the expression \keyword{this} is a prvalue of type ``pointer to @@ -1255,8 +1297,8 @@ between the optional \grammarterm{cv-qualifier-seq} and the end of the \grammarterm{function-definition}, \grammarterm{member-declarator}, or \grammarterm{declarator}. It shall not appear within -the declaration of either -a static member function or an explicit object member function +the declaration of +a static or explicit object member function of the current class (although its type and value category are defined within such member functions as they are within an implicit object member function). @@ -1357,6 +1399,10 @@ \end{itemize} the \grammarterm{id-expression} is transformed into a class member access expression using \tcode{(*this)} as the object expression. +If this transformation occurs +in the predicate of a precondition assertion of a constructor of \tcode{X} +or a postcondition assertion of a destructor of \tcode{X}, +the expression is ill-formed. \begin{note} If \tcode{C} is not \tcode{X} or a base class of \tcode{X}, the class member access expression is ill-formed. @@ -1366,6 +1412,16 @@ \end{note} This transformation does not apply in the template definition context\iref{temp.dep.type}. +\begin{example} +\begin{codeblock} +struct C { + bool b; + C() pre(b) // error + pre(&this->b) // OK + pre(sizeof(b) > 0); // OK, \tcode{b} is not potentially evaluated. +}; +\end{codeblock} +\end{example} \pnum If an \grammarterm{id-expression} $E$ denotes @@ -1466,10 +1522,8 @@ \indextext{identifier}% An \grammarterm{identifier} is only an \grammarterm{id-expression} if it has -been suitably declared\iref{dcl.dcl} +been suitably declared\iref{dcl} or if it appears as part of a \grammarterm{declarator-id}\iref{dcl.decl}. -An \grammarterm{identifier} that names a coroutine parameter -refers to the copy of the parameter\iref{dcl.fct.def.coroutine}. \begin{note} For \grammarterm{operator-function-id}{s}, see~\ref{over.oper}; for \grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for @@ -1500,21 +1554,28 @@ \pnum The result is the entity denoted by the \grammarterm{unqualified-id}\iref{basic.lookup.unqual}. -If the \grammarterm{unqualified-id} appears -in a \grammarterm{lambda-expression} at program point $P$ and -the entity is a local entity\iref{basic.pre} or a variable declared by -an \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, -then let $S$ be the \grammarterm{compound-statement} of -the innermost enclosing \grammarterm{lambda-expression} of $P$. -If naming the entity from outside of an unevaluated operand within $S$ -would refer to an entity -captured by copy in some intervening \grammarterm{lambda-expression}, -then let $E$ be the innermost such \grammarterm{lambda-expression}. + +\pnum +If \begin{itemize} \item -If there is such a \grammarterm{lambda-expression} and -if $P$ is in $E$'s function parameter scope -but not its \grammarterm{parameter-declaration-clause}, then +the \grammarterm{unqualified-id} +appears in a \grammarterm{lambda-expression} +at program point $P$, +\item +the entity is a local entity\iref{basic.pre} +or a variable declared by an \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, +\item +naming the entity within the \grammarterm{compound-statement} of +the innermost enclosing \grammarterm{lambda-expression} of $P$, +but not in an unevaluated operand, would refer to an entity captured by copy +in some intervening \grammarterm{lambda-expression}, and +\item +$P$ is in the function parameter scope, +but not the \grammarterm{parameter-declaration-clause}, +of the innermost such \grammarterm{lambda-expression} $E$, +\end{itemize} +then the type of the expression is the type of a class member access expression\iref{expr.ref} naming the non-static data member @@ -1524,26 +1585,166 @@ If $E$ is not declared \keyword{mutable}, the type of such an identifier will typically be \keyword{const} qualified. \end{note} + +\pnum +Otherwise, +if the \grammarterm{unqualified-id} +names a coroutine parameter, +the type of the expression is +that of the copy of the parameter\iref{dcl.fct.def.coroutine}, +and the result is that copy. + +\pnum +Otherwise, +if the \grammarterm{unqualified-id} +names a result binding\iref{dcl.contract.res} +attached to a function \placeholder{f} +with return type \tcode{U}, +\begin{itemize} +\item +if \tcode{U} is ``reference to \tcode{T}'', +then the type of the expression is +\tcode{const T}; \item -Otherwise (if there is no such \grammarterm{lambda-expression} or -if $P$ either precedes $E$'s function parameter scope or -is in $E$'s \grammarterm{parameter-declaration-clause}), -the type of the expression is the type of the result. +otherwise, +the type of the expression is \tcode{const U}. \end{itemize} -If the entity is a template parameter object for + +\pnum +Otherwise, +if the \grammarterm{unqualified-id} +appears in the predicate of a contract assertion $C$\iref{basic.contract} +and the entity is +\begin{itemize} +\item +a variable +declared outside of $C$ +of object type \tcode{T}, +\item +a variable or template parameter +declared outside of $C$ +of type ``reference to \tcode{T}'', or +\item +a structured binding +of type \tcode{T} +whose corresponding variable +is declared outside of $C$, +\end{itemize} +then the type of the expression is \keyword{const}~\tcode{T}. + +\pnum +\begin{example} +\begin{codeblock} +int n = 0; +struct X { bool m(); }; + +struct Y { + int z = 0; + + void f(int i, int* p, int& r, X x, X* px) + pre (++n) // error: attempting to modify const lvalue + pre (++i) // error: attempting to modify const lvalue + pre (++(*p)) // OK + pre (++r) // error: attempting to modify const lvalue + pre (x.m()) // error: calling non-const member function + pre (px->m()) // OK + pre ([=,&i,*this] mutable { + ++n; // error: attempting to modify const lvalue + ++i; // error: attempting to modify const lvalue + ++p; // OK, refers to member of closure type + ++r; // OK, refers to non-reference member of closure type + ++this->z; // OK, captured \tcode{*\keyword{this}} + ++z; // OK, captured \tcode{*\keyword{this}} + int j = 17; + [&]{ + int k = 34; + ++i; // error: attempting to modify const lvalue + ++j; // OK + ++k; // OK + }(); + return true; + }()); + + template + void g() + pre(++N) // error: attempting to modify prvalue + pre(++R) // error: attempting to modify const lvalue + pre(++(*P)); // OK + + int h() + post(r : ++r) // error: attempting to modify const lvalue + post(r: [=] mutable { + ++r; // OK, refers to member of closure type + return true; + }()); + + int& k() + post(r : ++r); // error: attempting to modify const lvalue +}; +\end{codeblock} +\end{example} + +\pnum +Otherwise, if the entity is a template parameter object for a template parameter of type \tcode{T}\iref{temp.param}, the type of the expression is \tcode{const T}. + +\pnum In all other cases, the type of the expression is the type of the entity. + +\pnum \begin{note} The type will be adjusted as described in \ref{expr.type} if it is cv-qualified or is a reference type. \end{note} + +\pnum The expression is an xvalue if it is move-eligible (see below); an lvalue -if the entity is a function, variable, structured binding\iref{dcl.struct.bind}, data member, or +if the entity is a +function, +variable, +structured binding\iref{dcl.struct.bind}, +result binding\iref{dcl.contract.res}, +data member, or template parameter object; and a prvalue otherwise\iref{basic.lval}; it is a bit-field if the identifier designates a bit-field. + +\pnum +If an \grammarterm{id-expression} $E$ +appears in the predicate of +a function contract assertion attached to a function \placeholder{f} +and denotes +a function parameter of \placeholder{f} +and the implementation introduces any temporary objects +to hold the value of that parameter as specified in \ref{class.temporary}, +\begin{itemize} +\item +if the contract assertion +is a precondition assertion +and the evaluation of the precondition assertion +is sequenced before the initialization of the parameter object, +$E$ refers to the most recently initialized such temporary object, and +\item +if the contract assertion +is a postcondition assertion, +it is unspecified whether $E$ refers to +one of the temporary objects or the parameter object; +the choice is consistent within a single evaluation of a postcondition assertion. +\end{itemize} + +\pnum +If an \grammarterm{id-expression} $E$ +names a result binding +in a postcondition assertion +and the implementation introduces any temporary objects +to hold the result object as specified in \ref{class.temporary}, +and the postcondition assertion +is sequenced before the initialization of the result object\iref{expr.call}, +$E$ refers to the most recently initialized such temporary object. + + \begin{example} \begin{codeblock} void f() { @@ -1575,30 +1776,26 @@ \pnum An \defnadj{implicitly movable}{entity} is -a variable of automatic storage duration +a variable with automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type. -In the following contexts, -an \grammarterm{id-expression} is \defn{move-eligible}: +An \grammarterm{id-expression} is \defn{move-eligible} if \begin{itemize} \item -If the \grammarterm{id-expression} (possibly parenthesized) -is the operand of a \tcode{return}\iref{stmt.return} or -\keyword{co_return}\iref{stmt.return.coroutine} statement, -and names an implicitly movable entity declared in the body -or \grammarterm{parameter-declaration-clause} of the innermost enclosing -function or \grammarterm{lambda-expression}, or -\item -if the \grammarterm{id-expression} (possibly parenthesized) -is the operand of a \grammarterm{throw-expression}\iref{expr.throw}, -and names an implicitly movable entity -that belongs to a scope that does not contain the \grammarterm{compound-statement} -of the innermost -\grammarterm{lambda-expression}, -\grammarterm{try-block}, or -\grammarterm{function-try-block} (if any) -whose \grammarterm{compound-statement} or \grammarterm{ctor-initializer} -contains the \grammarterm{throw-expression}. +it names an implicitly movable entity, +\item +it is the (possibly parenthesized) +operand of a \tcode{return}\iref{stmt.return} or +\keyword{co_return}\iref{stmt.return.coroutine} statement or +of a \grammarterm{throw-expression}\iref{expr.throw}, and +\item +each intervening scope between +the declaration of the entity and +the innermost enclosing scope of the \grammarterm{id-expression} +is a block scope and, +for a \grammarterm{throw-expression}, +is not the block scope of +a \grammarterm{try-block} or \grammarterm{function-try-block}. \end{itemize} \rSec3[expr.prim.id.qual]{Qualified names} @@ -1649,7 +1846,7 @@ a declarative \grammarterm{nested-name-specifier}. \end{itemize} A declarative \grammarterm{nested-name-specifier} -shall not have a \grammarterm{decltype-specifier}. +shall not have a \grammarterm{computed-type-specifier}. A declaration that uses a declarative \grammarterm{nested-name-specifier} shall be a friend declaration or inhabit a scope that contains the entity being redeclared or specialized. @@ -1697,7 +1894,32 @@ \pnum The result of a \grammarterm{qualified-id} $Q$ is the entity it denotes\iref{basic.lookup.qual}. -The type of the expression is the type of the result. + +\pnum +If $Q$ appears +in the predicate of a contract assertion $C$\iref{basic.contract} +and the entity is +\begin{itemize} +\item +a variable +declared outside of $C$ +of object type \tcode{T}, +\item +a variable +declared outside of $C$ +of type ``reference to \tcode{T}'', or +\item +a structured binding of type \tcode{T} +whose corresponding variable +is declared outside of $C$, +\end{itemize} +then the type of the expression is \keyword{const}~\tcode{T}. + + +\pnum +Otherwise, the type of the expression is the type of the result. + +\pnum The result is an lvalue if the member is \begin{itemize} \item @@ -1797,10 +2019,11 @@ \begin{bnf} \nontermdef{lambda-declarator}\br lambda-specifier-seq \opt{noexcept-specifier} \opt{attribute-specifier-seq} \opt{trailing-return-type}\br - noexcept-specifier \opt{attribute-specifier-seq} \opt{trailing-return-type}\br - \opt{trailing-return-type}\br + \bnfindent \opt{function-contract-specifier-seq}\br + noexcept-specifier \opt{attribute-specifier-seq} \opt{trailing-return-type} \opt{function-contract-specifier-seq}\br + \opt{trailing-return-type} \opt{function-contract-specifier-seq}\br \terminal{(} parameter-declaration-clause \terminal{)} \opt{lambda-specifier-seq} \opt{noexcept-specifier} \opt{attribute-specifier-seq}\br - \bnfindent \opt{trailing-return-type} \opt{requires-clause} + \bnfindent \opt{trailing-return-type} \opt{requires-clause} \opt{function-contract-specifier-seq} \end{bnf} \begin{bnf} @@ -1813,8 +2036,7 @@ \begin{bnf} \nontermdef{lambda-specifier-seq}\br - lambda-specifier\br - lambda-specifier lambda-specifier-seq + lambda-specifier \opt{lambda-specifier-seq} \end{bnf} \pnum @@ -1901,8 +2123,9 @@ if the lambda has a \grammarterm{template-parameter-list}. \begin{example} \begin{codeblock} -int i = [](int i, auto a) { return i; }(3, 4); // OK, a generic lambda -int j = [](T t, int i) { return i; }(3, 4); // OK, a generic lambda +auto x = [](int i, auto a) { return i; }; // OK, a generic lambda +auto y = [](this auto self, int i) { return i; }; // OK, a generic lambda +auto z = [](int i) { return i; }; // OK, a generic lambda \end{codeblock} \end{example} @@ -1934,9 +2157,9 @@ other than by changing: \begin{itemize} \item the size and/or alignment of the closure type, - -\item whether the closure type is trivially copyable\iref{class.prop}, or - +\item whether the closure type is trivially copyable\iref{class.prop}, +\item whether the closure type is trivially relocatable\iref{class.prop}, +\item whether the closure type is replaceable\iref{class.prop}, or \item whether the closure type is a standard-layout class\iref{class.prop}. \end{itemize} @@ -1999,7 +2222,7 @@ \item the closure type, \item -a class type derived from the closure type, or +a class type publicly and unambiguously derived from the closure type, or \item a reference to a possibly cv-qualified such type. \end{itemize} @@ -2031,8 +2254,9 @@ followed by \keyword{mutable} and the \grammarterm{lambda-declarator} does not contain an explicit object parameter. -It is neither virtual nor declared \tcode{volatile}. Any -\grammarterm{noexcept-specifier} specified on a \grammarterm{lambda-expression} +It is neither virtual nor declared \tcode{volatile}. +Any \grammarterm{noexcept-specifier} or \grammarterm{function-contract-specifier}\iref{dcl.contract.func} +specified on a \grammarterm{lambda-expression} applies to the corresponding function call operator or operator template. An \grammarterm{attribute-specifier-seq} in a \grammarterm{lambda-declarator} appertains to the type of the corresponding function call operator or operator template. @@ -2111,9 +2335,55 @@ \end{example} \end{note} +\pnum +If all potential references +to a local entity implicitly captured by a \grammarterm{lambda-expression} $L$ +occur within the function contract assertions\iref{dcl.contract.func} +of the call operator or operator template of $L$ +or within \grammarterm{assertion-statement}s\iref{stmt.contract.assert} +within the body of $L$, +the program is ill-formed. +\begin{note} +Adding a contract assertion to an existing \Cpp{} program cannot +cause additional captures. +\end{note} +\begin{example} +\begin{codeblock} +static int i = 0; + +void test() { + auto f1 = [=] pre(i > 0) {}; // OK, no local entities are captured. + + int i = 1; + auto f2 = [=] pre(i > 0) {}; // error: cannot implicitly capture \tcode{i} here + auto f3 = [i] pre(i > 0) {}; // OK, \tcode{i} is captured explicitly. + + auto f4 = [=] { + contract_assert(i > 0); // error: cannot implicitly capture \tcode{i} here + }; + + auto f5 = [=] { + contract_assert(i > 0); // OK, \tcode{i} is referenced elsewhere. + (void)i; + }; + + auto f6 = [=] pre( // \#1 + []{ + bool x = true; + return [=]{ return x; }(); // OK, \#1 captures nothing. + }()) {}; + + bool y = true; + auto f7 = [=] pre([=]{ return y; }()); // error: outer capture of \tcode{y} is invalid. +} +\end{codeblock} +\end{example} + + \pnum The closure type for a non-generic \grammarterm{lambda-expression} with no \grammarterm{lambda-capture} +and no explicit object parameter\iref{dcl.fct} whose constraints (if any) are satisfied has a conversion function to pointer to function with \Cpp{} language linkage\iref{dcl.link} having @@ -2123,9 +2393,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 @@ -2134,7 +2404,9 @@ if the function call operator is an immediate function. \pnum -For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a +For a generic lambda with no \grammarterm{lambda-capture} +and no explicit object parameter\iref{dcl.fct}, +the closure type has a conversion function template to pointer to function. The conversion function template has the same invented template parameter list, and the pointer to function has the same @@ -2198,10 +2470,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 @@ -2327,7 +2599,7 @@ \pnum The body of a \grammarterm{lambda-expression} may refer to local entities -of enclosing block scopes by capturing those entities, as described +of enclosing scopes by capturing those entities, as described below. \pnum @@ -2343,7 +2615,7 @@ or ``\tcode{* \keyword{this}}''. \begin{note} The form \tcode{[\&,\keyword{this}]} is redundant but accepted -for compatibility with ISO \CppXIV{}. +for compatibility with \CppXIV{}. \end{note} Ignoring appearances in \grammarterm{initializer}{s} of \grammarterm{init-capture}{s}, an identifier or @@ -2368,10 +2640,19 @@ A \grammarterm{lambda-expression} shall not have a \grammarterm{capture-default} or \grammarterm{simple-capture} in its \grammarterm{lambda-introducer} -unless its innermost enclosing scope is a block scope\iref{basic.scope.block} -or it appears within a default member initializer +unless +\begin{itemize} +\item +its innermost enclosing scope is a block scope\iref{basic.scope.block}, +\item +it appears within a default member initializer and its innermost enclosing scope is -the corresponding class scope\iref{basic.scope.class}. +the corresponding class scope\iref{basic.scope.class}, or +\item +it appears within a contract assertion +and its innermost enclosing scope +is the corresponding contract-assertion scope\iref{basic.scope.contract}. +\end{itemize} \pnum The \grammarterm{identifier} in a \grammarterm{simple-capture} @@ -2609,8 +2890,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 @@ -2640,7 +2921,7 @@ void g() { const int N = 10; [=] { - int arr[N]; // OK, not an odr-use, refers to automatic variable + int arr[N]; // OK, not an odr-use, refers to variable with automatic storage duration f(&N); // OK, causes \tcode{N} to be captured; \tcode{\&N} points to // the corresponding member of the closure type }; @@ -2828,6 +3109,9 @@ } \end{codeblock} \end{example} + +\pnum +A fold expression is a pack expansion. \indextext{expression!fold|)}% \rSec2[expr.prim.req]{Requires expressions} @@ -2852,15 +3136,14 @@ \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{requirement-body}\br \terminal{\{} requirement-seq \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{requirement-seq}\br - requirement\br - requirement requirement-seq + requirement \opt{requirement-seq} \end{bnf} \begin{bnf} @@ -2874,8 +3157,6 @@ \pnum A \grammarterm{requires-expression} is a prvalue of type \tcode{bool} whose value is described below. -Expressions appearing within a \grammarterm{requirement-body} -are unevaluated operands\iref{term.unevaluated.operand}. \pnum \begin{example} @@ -2967,10 +3248,10 @@ \pnum A \grammarterm{simple-requirement} asserts the validity of an \grammarterm{expression}. +The \grammarterm{expression} is an unevaluated operand. \begin{note} The enclosing \grammarterm{requires-expression} will evaluate to \keyword{false} if substitution of template arguments into the \grammarterm{expression} fails. -The \grammarterm{expression} is an unevaluated operand\iref{term.unevaluated.operand}. \end{note} \begin{example} \begin{codeblock} @@ -3038,7 +3319,9 @@ \pnum A \grammarterm{compound-requirement} asserts properties -of the \grammarterm{expression} $E$. Substitution +of the \grammarterm{expression} $E$. +The \grammarterm{expression} is an unevaluated operand. +Substitution of template arguments (if any) and verification of semantic properties proceed in the following order: @@ -3203,12 +3486,12 @@ a possibly empty, comma-separated list of \grammarterm{initializer-clause}s that constitute the arguments to the subscript operator. The \grammarterm{postfix-expression} and -the initialization of the object parameter of -any applicable subscript operator function is sequenced before +the initialization of the object parameter\iref{dcl.fct} of +any applicable subscript operator function\iref{over.sub} is sequenced before each expression in the \grammarterm{expression-list} and also before -any default argument. +any default argument\iref{dcl.fct.default}. The initialization of a non-object parameter of -a subscript operator function \tcode{S}\iref{over.sub}, +a subscript operator function \tcode{S}, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other non-object parameter of \tcode{S}. @@ -3329,7 +3612,9 @@ \indextext{initialization!parameter}% When a function is called, each parameter\iref{dcl.fct} is initialized\iref{dcl.init,class.copy.ctor} with -its corresponding argument. +its corresponding argument, +and each precondition assertion of the function +is evaluated.\iref{dcl.contract.func} If the function is an explicit object member function and there is an implied object argument\iref{over.call.func}, the list of provided arguments is preceded by the implied object argument @@ -3345,9 +3630,9 @@ If the function is an implicit object member function, the object expression of the class member access shall be a glvalue and -the \keyword{this} parameter of the function\iref{expr.prim.this} -is initialized with a pointer to the object of the call, converted -as if by an explicit type conversion\iref{expr.cast}. +the implicit object parameter of the function\iref{over.match.funcs} +is initialized with that glvalue, +converted as if by an explicit type conversion\iref{expr.cast}. \begin{note} There is no access or ambiguity checking on this conversion; the access checking and disambiguation are done as part of the (possibly implicit) @@ -3365,7 +3650,7 @@ It is \impldef{whether a parameter is destroyed when the function exits or at the end of the enclosing full-expression} whether a parameter is destroyed -when the function in which it is defined exits\iref{stmt.return, except.ctor} +when the function in which it is defined exits\iref{stmt.return, except.ctor, expr.await} or at the end of the enclosing full-expression; parameters are always destroyed in the reverse order of their construction. The initialization and destruction of each parameter occurs @@ -3389,9 +3674,21 @@ The \grammarterm{postfix-expression} is sequenced before each \grammarterm{expression} in the \grammarterm{expression-list} and any default argument. -The initialization of a parameter, +The initialization of a parameter or, +if the implementation introduces any temporary objects +to hold the values of function parameters\iref{class.temporary}, +the initialization of those temporaries, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter. +These evaluations are +sequenced before +the evaluation of the precondition assertions of the function, +which are evaluated in sequence\iref{dcl.contract.func}. +For any temporaries +introduced to hold the values of function parameters, +the initialization of the parameter objects from those temporaries +is indeterminately sequenced with respect to +the evaluation of each precondition assertion. \begin{note} All side effects of argument evaluations are sequenced before the function is @@ -3437,6 +3734,18 @@ chosen function, the value returned from the final overrider is converted to the return type of the statically chosen function. +\pnum +When the called function exits normally\iref{stmt.return,expr.await}, +all postcondition assertions of the function +are evaluated in sequence\iref{dcl.contract.func}. +If the implementation introduces any temporary objects +to hold the result value as specified in \ref{class.temporary}, +the evaluation of each postcondition assertion +is indeterminately sequenced with respect to +the initialization of any of those temporaries or the result object. +These evaluations, in turn, are sequenced before +the destruction of any function parameters. + \pnum \begin{note} \indextext{type checking!argument}% @@ -3473,7 +3782,7 @@ \indextext{ellipsis!conversion sequence}% When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the -argument by invoking \tcode{va_arg}\iref{support.runtime}. +argument by invoking \libmacro{va_arg}\iref{support.runtime}. \begin{note} This paragraph does not apply to arguments passed to a function parameter pack. Function parameter packs are expanded during template instantiation\iref{temp.variadic}, @@ -3513,6 +3822,9 @@ if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise. +If it is a non-void prvalue, +the type of the function call expression shall be complete, +except as specified in \ref{dcl.type.decltype}. \rSec3[expr.type.conv]{Explicit type conversion (functional notation)} @@ -3539,6 +3851,44 @@ Otherwise, if the type contains a placeholder type, it is replaced by the type determined by placeholder type deduction\iref{dcl.type.auto.deduct}. +Let \tcode{T} denote the resulting type. +Then: + +\begin{itemize} +\item +If the initializer is a parenthesized single expression, +the type conversion expression is equivalent +to the corresponding cast +expression\iref{expr.cast}. + +\item +\indextext{type!incomplete}% +Otherwise, if \tcode{T} is \cv{}~\keyword{void}, +the initializer shall be \tcode{()} or \tcode{\{\}} +(after pack expansion, if any), and +the expression is a prvalue of type \keyword{void} +that performs no initialization. + +\item +Otherwise, if \tcode{T} is a reference type, +the expression has the same effect as +direct-initializing an invented variable \tcode{t} of type \tcode{T} from +the initializer and then +using \tcode{t} as the result of the expression; +the result is an lvalue if +\tcode{T} is an lvalue reference type or +an rvalue reference to function type and +an xvalue otherwise. + +\item +Otherwise, +the expression is a prvalue of type \tcode{T} +whose result object is direct-initialized\iref{dcl.init} +with the initializer. +\end{itemize} + +If the initializer is a parenthesized optional \grammarterm{expression-list}, +\tcode{T} shall not be an array type. \begin{example} \begin{codeblock} struct A {}; @@ -3553,24 +3903,6 @@ \end{codeblock} \end{example} -\pnum -If the initializer is a parenthesized single expression, -the type conversion expression is equivalent -to the corresponding cast -expression\iref{expr.cast}. -\indextext{type!incomplete}% -Otherwise, if the type is \cv{}~\keyword{void} -and the initializer is \tcode{()} or \tcode{\{\}} -(after pack expansion, if any), -the expression is a prvalue of type \keyword{void} -that performs no initialization. -Otherwise, -the expression is a prvalue of the specified type -whose result object is direct-initialized\iref{dcl.init} -with the initializer. -If the initializer is a parenthesized optional \grammarterm{expression-list}, -the specified type shall not be an array type. - \rSec3[expr.ref]{Class member access} \pnum @@ -3756,8 +4088,8 @@ \indextext{operator!increment}% \indextext{\idxcode{++}|see{operator, increment}}% \indextext{postfix \tcode{++}}% -The value of a postfix \tcode{++} expression is the value of its -operand. +The value of a postfix \tcode{++} expression is the value obtained by +applying the lvalue-to-rvalue conversion\iref{conv.lval} to its operand. \begin{note} The value obtained is a copy of the original value. \end{note} @@ -3857,6 +4189,22 @@ \pnum If \tcode{v} is a null pointer value, the result is a null pointer value. +\pnum +If \tcode{v} has type ``pointer to \cv{}~\tcode{U}'' and +\tcode{v} does not point to an object +whose type is similar\iref{conv.qual} to \tcode{U} and +that is +within its lifetime or +within its period of construction or destruction\iref{class.cdtor}, +the behavior is undefined. +If \tcode{v} is a glvalue of type \tcode{U} and +\tcode{v} does not refer to an object +whose type is similar to \tcode{U} and +that is +within its lifetime or +within its period of construction or destruction, +the behavior is undefined. + \pnum If \tcode{T} is ``pointer to \cv{} \keyword{void}'', then the result is a pointer to the most derived object pointed to by \tcode{v}. @@ -4087,7 +4435,22 @@ a program that necessitates such a cast is ill-formed. \pnum -An expression $E$ can be explicitly converted to a type \tcode{T} +Any expression can be explicitly converted to type \cv{}~\keyword{void}, +in which case the operand is a discarded-value expression\iref{expr.prop}. +\begin{note} +Such a \keyword{static_cast} has no result +as it is a prvalue of type \keyword{void}; see~\ref{basic.lval}. +\end{note} +\begin{note} +However, if the value is in a temporary +object\iref{class.temporary}, the destructor for that +object is +not executed until the usual time, and the value of the object is +preserved for the purpose of executing the destructor. +\end{note} + +\pnum +Otherwise, an expression $E$ can be explicitly converted to a type \tcode{T} if there is an implicit conversion sequence\iref{over.best.ics} from $E$ to \tcode{T}, if overload resolution for a direct-initialization\iref{dcl.init} @@ -4115,28 +4478,8 @@ \end{note} \pnum -Otherwise, the \keyword{static_cast} shall perform one of the conversions -listed below. No other conversion shall be performed explicitly using a -\keyword{static_cast}. - -\pnum -Any expression can be explicitly converted to type \cv{}~\keyword{void}, -in which case the operand is a discarded-value expression\iref{expr.prop}. -\begin{note} -Such a \keyword{static_cast} has no result -as it is a prvalue of type \keyword{void}; see~\ref{basic.lval}. -\end{note} -\begin{note} -However, if the value is in a temporary -object\iref{class.temporary}, the destructor for that -object is -not executed until the usual time, and the value of the object is -preserved for the purpose of executing the destructor. -\end{note} - - -\pnum -The inverse of any standard conversion sequence\iref{conv} not containing an +Otherwise, +the inverse of a standard conversion sequence\iref{conv} not containing an lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, function-to-pointer\iref{conv.func}, @@ -4280,6 +4623,9 @@ \end{codeblock} \end{example} +\pnum +No other conversion can be performed using \keyword{static_cast}. + \rSec3[expr.reinterpret.cast]{Reinterpret cast} \pnum @@ -4358,9 +4704,6 @@ \tcode{T2}'' (where \tcode{T1} and \tcode{T2} are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. -\begin{note} -See also~\ref{conv.ptr} for more details of pointer conversions. -\end{note} \pnum An object pointer @@ -4435,22 +4778,25 @@ \indextext{cast!reinterpret!reference}% \indextext{cast!reference}% \indextext{type pun}% -A glvalue of type \tcode{T1}, +If \tcode{v} is a glvalue of type \tcode{T1}, designating an object or function \placeholder{x}, -can be cast to the type ``reference to \tcode{T2}'' +it can be cast to the type ``reference to \tcode{T2}'' if an expression of type ``pointer to \tcode{T1}'' can be explicitly converted to the type ``pointer to \tcode{T2}'' using a \keyword{reinterpret_cast}. The result is that of \tcode{*reinterpret_cast(p)} where \tcode{p} is a pointer to \placeholder{x} of type ``pointer to \tcode{T1}''. -No temporary is created, no copy is made, and +\begin{note} +No temporary is materialized\iref{conv.rval} or created, +no copy is made, and no constructors\iref{class.ctor} or conversion functions\iref{class.conv} are called. \begin{footnote} This is sometimes referred to as a type pun when the result refers to the same object as the source glvalue. \end{footnote} +\end{note} \rSec3[expr.const.cast]{Const cast} @@ -4464,7 +4810,10 @@ otherwise, the result is a prvalue and the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} standard conversions are -performed on the expression \tcode{v}. Conversions that can be performed explicitly using +performed on the expression \tcode{v}. +The temporary materialization conversion\iref{conv.rval} is not +performed on \tcode{v}, other than as specified below. +Conversions that can be performed explicitly using \keyword{const_cast} are listed below. No other conversion shall be performed explicitly using \keyword{const_cast}. @@ -4475,23 +4824,16 @@ \end{note} \pnum -For two similar types \tcode{T1} and \tcode{T2}\iref{conv.qual}, -a prvalue of type \tcode{T1} may be explicitly +For two similar object pointer or pointer to data member types +\tcode{T1} and \tcode{T2}\iref{conv.qual}, +a prvalue of type \tcode{T1} can be explicitly converted to the type \tcode{T2} using a \keyword{const_cast} if, considering the qualification-decompositions of both types, each $P^1_i$ is the same as $P^2_i$ for all $i$. -The result of a \keyword{const_cast} refers to the original entity. -\begin{example} -\begin{codeblock} -typedef int *A[3]; // array of 3 pointer to \tcode{int} -typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} - -CA &&r = A{}; // OK, reference binds to temporary array object - // after qualification conversion to type \tcode{CA} -A &&r1 = const_cast(CA{}); // error: temporary array decayed to pointer -A &&r2 = const_cast(CA{}); // OK -\end{codeblock} -\end{example} +If \tcode{v} is a null pointer or null member pointer, +the result is a null pointer or null member pointer, respectively. +Otherwise, the result points to or past the end of the same object, or +points to the same member, respectively, as \tcode{v}. \pnum For two object types \tcode{T1} and \tcode{T2}, if a pointer to \tcode{T1} can @@ -4504,20 +4846,22 @@ \item a glvalue of type \tcode{T1} can be explicitly converted to an xvalue of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}; and -\item if \tcode{T1} is a class type, a prvalue of type \tcode{T1} can be +\item if \tcode{T1} is a class or array type, +a prvalue of type \tcode{T1} can be explicitly converted to an xvalue of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}. +The temporary materialization conversion is performed on \tcode{v}. \end{itemize} -The result of a reference \keyword{const_cast} refers -to the original object if the operand is a glvalue and -to the result of applying the temporary materialization conversion\iref{conv.rval} otherwise. +The result refers to the same object as the (possibly converted) operand. +\begin{example} +\begin{codeblock} +typedef int *A[3]; // array of 3 pointer to \tcode{int} +typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} -\pnum -A null pointer value\iref{basic.compound} is converted to the null pointer -value of the destination type. The null member pointer -value\iref{conv.mem} is converted to the null member pointer value of -the destination type. +auto &&r2 = const_cast(CA{}); // OK, temporary materialization conversion is performed +\end{codeblock} +\end{example} \pnum \begin{note} @@ -4791,7 +5135,7 @@ An operand with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. The expression \tcode{++x} is otherwise equivalent to \tcode{x+=1} and -the expression \tcode{--x} is otherwise equivalent to \tcode{x-=1}\iref{expr.ass}. +the expression \tcode{--x} is otherwise equivalent to \tcode{x-=1}\iref{expr.assign}. \begin{note} For postfix increment and decrement, see~\ref{expr.post.incr}. \end{note} @@ -4827,6 +5171,9 @@ default argument\iref{dcl.fct.default}. An \grammarterm{await-expression} shall not appear in the initializer of a block variable with static or thread storage duration. +An \grammarterm{await-expression} shall not be +a potentially-evaluated subexpression +of the predicate of a contract assertion\iref{basic.contract}. A context within a function where an \grammarterm{await-expression} can appear is called a \term{suspension context} of the function. @@ -5081,7 +5428,7 @@ \begin{note} A \keyword{sizeof} expression is an integral constant expression\iref{expr.const}. -The type \tcode{std::size_t} is defined in the standard header +The \grammarterm{typedef-name} \tcode{std::size_t} is declared in the standard header \libheader{cstddef}\iref{cstddef.syn,support.types.layout}. \end{note} @@ -5100,7 +5447,7 @@ \begin{note} An \keyword{alignof} expression is an integral constant expression\iref{expr.const}. -The type \tcode{std::size_t} is defined in the standard header +The \grammarterm{typedef-name} \tcode{std::size_t} is declared in the standard header \libheader{cstddef}\iref{cstddef.syn,support.types.layout}. \end{note} @@ -5285,6 +5632,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 @@ -5301,7 +5657,7 @@ If the \grammarterm{expression} in a \grammarterm{noptr-new-declarator} is present, it is implicitly converted to \tcode{std::size_t}. \indextext{function!allocation}% -The value of the \grammarterm{expression} is invalid if: +The value of the \grammarterm{expression} is invalid if \begin{itemize} \item the expression is of non-class type and its value before converting to @@ -5441,12 +5797,7 @@ \pnum During an evaluation of a constant expression, -a call to an allocation function is always omitted. -\begin{note} -Only \grammarterm{new-expression}{s} that would otherwise result in -a call to a replaceable global allocation function -can be evaluated in constant expressions\iref{expr.const}. -\end{note} +a call to a replaceable allocation function is always omitted\iref{expr.const}. \pnum The implementation may @@ -5774,22 +6125,15 @@ If the operand is of class type, it is contextually implicitly converted\iref{conv} to a pointer to object -type. -\begin{footnote} -This implies that an object -cannot be deleted using a pointer of type -\tcode{\keyword{void}*} because \keyword{void} is not an object type. -\end{footnote} +type +and the converted operand is used in place of the original operand +for the remainder of this subclause. Otherwise, it shall be a prvalue of pointer to object type. The \grammarterm{delete-expression} has type \keyword{void}. \pnum \indextext{\idxcode{delete}!single-object}% -If the operand has a class type, the operand is converted to a pointer -type by calling the above-mentioned conversion function, and the -converted operand is used in place of the original operand for the -remainder of this subclause. In a single-object delete expression, the value of the operand of \keyword{delete} may be a null pointer value, a pointer value @@ -5833,15 +6177,10 @@ expression, if the dynamic type of the object to be deleted is not similar to its static type, the behavior is undefined. -\pnum -The \grammarterm{cast-expression} in a \grammarterm{delete-expression} shall -be evaluated exactly once. - \pnum \indextext{type!incomplete}% -If the object being deleted has incomplete class type at the point of -deletion and the complete class has a non-trivial destructor or a -deallocation function, the behavior is undefined. +If the object being deleted has incomplete class type at the point of deletion, +the program is ill-formed. \pnum \indextext{\idxcode{delete}!destructor and}% @@ -5935,7 +6274,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, @@ -6370,7 +6709,7 @@ \indextext{comparison!undefined pointer}% When two pointer expressions \tcode{P} and \tcode{Q} are subtracted, the type of the result is an \impldef{type of \tcode{ptrdiff_t}} signed -integral type; this type shall be the same type that is defined as +integral type; this type shall be the same type that is named by \tcode{std::ptrdiff_t} in the \libheader{cstddef} header\iref{support.types.layout}. \begin{itemize} @@ -6604,13 +6943,11 @@ \end{bnf} % The -lvalue-to-rvalue\iref{conv.lval}, -array-to-pointer\iref{conv.array}, +lvalue-to-rvalue\iref{conv.lval} and function-to-pointer\iref{conv.func} standard conversions are performed on the operands. -The comparison is deprecated if -both operands were of array type -prior to these conversions\iref{depr.array.comp}. +If one of the operands is a pointer, the +array-to-pointer conversion\iref{conv.array} is performed on the other operand. \pnum The converted operands shall have arithmetic, enumeration, or pointer type. @@ -6622,7 +6959,7 @@ \pnum The usual arithmetic conversions\iref{expr.arith.conv} are performed on operands of arithmetic -or enumeration type. If both operands are pointers, +or enumeration type. If both converted operands are pointers, pointer conversions\iref{conv.ptr}, function pointer conversions\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} @@ -6695,17 +7032,15 @@ The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators group left-to-right. The -lvalue-to-rvalue\iref{conv.lval}, -array-to-pointer\iref{conv.array}, +lvalue-to-rvalue\iref{conv.lval} and function-to-pointer\iref{conv.func} standard conversions are performed on the operands. -The comparison is deprecated if -both operands were of array type -prior to these conversions\iref{depr.array.comp}. +If one of the operands is a pointer or a null pointer constant\iref{conv.ptr}, +the array-to-pointer conversion\iref{conv.array} is performed +on the other operand. \pnum -The converted operands shall have arithmetic, enumeration, pointer, -or pointer-to-member type, or type \tcode{std::nullptr_t}. The operators +The converted operands shall have scalar type. The operators \tcode{==} and \tcode{!=} both yield \keyword{true} or \keyword{false}, i.e., a result of type \keyword{bool}. In each case below, the operands shall have the same type after the specified conversions have been applied. @@ -6713,7 +7048,7 @@ \pnum \indextext{comparison!pointer}% \indextext{comparison!pointer to function}% -If at least one of the operands is a pointer, +If at least one of the converted operands is a pointer, pointer conversions\iref{conv.ptr}, function pointer conversions\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} @@ -7037,13 +7372,18 @@ formed and at least one of the operands has (possibly cv-qualified) class type: \begin{itemize} \item if \tcode{T1} and \tcode{T2} are the same class type -(ignoring cv-qualification) and -\tcode{T2} is at least as cv-qualified as \tcode{T1}, -the target type is \tcode{T2}, +(ignoring cv-qualification): + \begin{itemize} + \item + if \tcode{T2} is at least as cv-qualified as \tcode{T1}, + the target type is \tcode{T2}, + \item + otherwise, no conversion sequence is formed for this operand; + \end{itemize} \item otherwise, if \tcode{T2} is a base class of \tcode{T1}, the target type is \cvqual{cv1} \tcode{T2}, where \cvqual{cv1} -denotes the cv-qualifiers of \tcode{T1}, +denotes the cv-qualifiers of \tcode{T1}; \item otherwise, the target type is the type that \tcode{E2} would have after applying the @@ -7056,12 +7396,14 @@ Using this process, it is determined whether an implicit conversion sequence can be formed from the second operand -to the target type determined for the third operand, and vice versa. -If both sequences can be formed, or one can be formed but it is the +to the target type determined for the third operand, and vice versa, +with the following outcome: +\begin{itemize} +\item If both sequences can be formed, or one can be formed but it is the ambiguous conversion sequence, the program is ill-formed. -If no conversion sequence can be formed, the operands are left unchanged +\item If no conversion sequence can be formed, the operands are left unchanged and further checking is performed as described below. -Otherwise, if exactly one conversion sequence can be formed, +\item Otherwise, if exactly one conversion sequence can be formed, that conversion is applied to the chosen operand and the converted operand is used in place of the original operand for the remainder of this subclause. @@ -7069,6 +7411,7 @@ The conversion might be ill-formed even if an implicit conversion sequence could be formed. \end{note} +\end{itemize} \pnum If the second and third operands are glvalues of the same value category @@ -7087,30 +7430,32 @@ subclause. \pnum -Lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +Array-to-pointer\iref{conv.array} and function-to-pointer\iref{conv.func} standard conversions are performed on the second and third operands. After those conversions, one of the following shall hold: \begin{itemize} \item The second and third operands have the same type; the result is of -that type and the result object is initialized using the selected operand. +that type and the result is copy-initialized using the selected operand. \item The second and third operands have arithmetic or enumeration type; the usual arithmetic conversions\iref{expr.arith.conv} are performed to bring them to a common type, and the result is of that type. \item One or both of the second and third operands have pointer type; -pointer conversions\iref{conv.ptr}, -function pointer conversions\iref{conv.fctptr}, and +lvalue-to-rvalue\iref{conv.lval}, +pointer\iref{conv.ptr}, +function pointer\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. \item One or both of the second and third operands have pointer-to-member type; -pointer to member conversions\iref{conv.mem}, -function pointer conversions\iref{conv.fctptr}, and +lvalue-to-rvalue\iref{conv.lval}, +pointer to member\iref{conv.mem}, +function pointer\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. @@ -7225,7 +7570,7 @@ \end{codeblock} \end{example} -\rSec2[expr.ass]{Assignment and compound assignment operators}% +\rSec2[expr.assign]{Assignment and compound assignment operators}% \indextext{expression!assignment and compound assignment} \pnum @@ -7277,9 +7622,13 @@ \end{bnf} \pnum -In simple assignment (\tcode{=}), the object referred to by the left operand -is modified\iref{defns.access} -by replacing its value with the result of the right operand. +In simple assignment (\tcode{=}), +let \tcode{V} be the result of the right operand; +the object referred to by the left operand is +modified\iref{defns.access} by replacing its value +with \tcode{V} or, +if the object is of integer type, +with the value congruent\iref{basic.fundamental} to \tcode{V}. \pnum \indextext{assignment!conversion by}% @@ -7338,7 +7687,7 @@ \item an assignment to an object of class type, in which case $B$ is passed as the argument to the assignment operator function selected by -overload resolution\iref{over.ass,over.match}. +overload resolution\iref{over.assign,over.match}. \end{itemize} \begin{example} @@ -7419,27 +7768,149 @@ \end{bnf} \pnum -A variable or temporary object \tcode{o} is \defn{constant-initialized} if +The \defnx{constituent values}{constituent value} of an object $o$ are \begin{itemize} \item - either it has an initializer or - its default-initialization results in some initialization being performed, and -\item - the full-expression of its initialization is a constant expression - when interpreted as a \grammarterm{constant-expression}, - except that if \tcode{o} is an object, - that full-expression - may also invoke constexpr constructors - for \tcode{o} and its subobjects - even if those objects are of non-literal class types. - \begin{note} - Such a class can have a non-trivial destructor. - Within this evaluation, - \tcode{std::is_constant_evaluated()}\iref{meta.const.eval} - returns \keyword{true}. +if $o$ has scalar type, the value of $o$; +\item +otherwise, the constituent values of any direct subobjects of $o$ +other than inactive union members. +\end{itemize} +The \defnx{constituent references}{constituent reference} of an object $o$ are +\begin{itemize} +\item +any direct members of $o$ that have reference type, and +\item +the constituent references of any direct subobjects of $o$ +other than inactive union members. +\end{itemize} + +\pnum +The constituent values and constituent references of +a variable \tcode{x} are defined as follows: +\begin{itemize} +\item +If \tcode{x} declares an object, +the constituent values and references of that object are +constituent values and references of \tcode{x}. +\item +If \tcode{x} declares a reference, +that reference is a constituent reference of \tcode{x}. +\end{itemize} +For any constituent reference \tcode{r} of a variable \tcode{x}, +if \tcode{r} is bound to a temporary object or subobject thereof +whose lifetime is extended to that of \tcode{r}, +the constituent values and references of that temporary object +are also constituent values and references of \tcode{x}, recursively. + +\pnum +An object $o$ is \defn{constexpr-referenceable} from a point $P$ if +\begin{itemize} +\item +$o$ has static storage duration, or +\item +$o$ has automatic storage duration, and, letting \tcode{v} denote +\begin{itemize} +\item +the variable corresponding to $o$'s complete object or +\item +the variable to whose lifetime that of $o$ is extended, +\end{itemize} +the smallest scope enclosing \tcode{v} and the smallest scope enclosing $P$ +that are neither +\begin{itemize} +\item +block scopes nor +\item +function parameter scopes associated with +a \grammarterm{requirement-parameter-list} +\end{itemize} +are the same function parameter scope. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { + int m; + const int& r; +}; +void f() { + static int sx; + thread_local int tx; // \tcode{tx} is never constexpr-referenceable + int ax; + A aa = {1, 2}; + static A sa = {3, 4}; + // The objects \tcode{sx}, \tcode{ax}, and \tcode{aa.m}, \tcode{sa.m}, and the temporaries to which \tcode{aa.r} and \tcode{sa.r} are bound, are constexpr-referenceable. + auto lambda = [] { + int ay; + // The objects \tcode{sx}, \tcode{sa.m}, and \tcode{ay} (but not \tcode{ax} or \tcode{aa}), and the + // temporary to which \tcode{sa.r} is bound, are constexpr-referenceable. + }; +} +\end{codeblock} +\end{example} + +\pnum +An object or reference \tcode{x} is +\defn{constexpr-representable} at a point $P$ if, +for each constituent value of \tcode{x} that points to or past an object $o$, +and for each constituent reference of \tcode{x} that refers to an object $o$, +$o$ is constexpr-referenceable from $P$. + +\pnum +\indextext{contract evaluation semantics!ignore} +A variable \tcode{v} is \defn{constant-initializable} if +\begin{itemize} +\item +the full-expression of its initialization is a constant expression +when interpreted as a \grammarterm{constant-expression} +with all contract assertions +using the ignore evaluation semantic\iref{basic.contract.eval}, +\begin{note} +Within this evaluation, +\tcode{std::is_constant_evaluated()}\iref{meta.const.eval} +returns \keyword{true}. +\end{note} +\begin{note} +The initialization, when evaluated, +can still evaluate contract assertions +with other evaluation semantics, +resulting in a diagnostic or ill-formed program +if a contract violation occurs. \end{note} +\item +immediately after the initializing declaration of \tcode{v}, +the object or reference \tcode{x} declared by \tcode{v} +is constexpr-representable, and +\item +if \tcode{x} has static or thread storage duration, +\tcode{x} is constexpr-representable at the nearest point +whose immediate scope is a namespace scope +that follows the initializing declaration of \tcode{v}. \end{itemize} +\pnum +A constant-initializable variable is \defn{constant-initialized} +if either it has an initializer or +its type is const-default-constructible\iref{dcl.init.general}. +\begin{example} +\begin{codeblock} +void f() { + int ax = 0; // \tcode{ax} is constant-initialized + thread_local int tx = 0; // \tcode{tx} is constant-initialized + static int sx; // \tcode{sx} is not constant-initialized + static int& rss = sx; // \tcode{rss} is constant-initialized + static int& rst = tx; // \tcode{rst} is not constant-initialized + static int& rsa = ax; // \tcode{rsa} is not constant-initialized + thread_local int& rts = sx; // \tcode{rts} is constant-initialized + thread_local int& rtt = tx; // \tcode{rtt} is not constant-initialized + thread_local int& rta = ax; // \tcode{rta} is not constant-initialized + int& ras = sx; // \tcode{ras} is constant-initialized + int& rat = tx; // \tcode{rat} is not constant-initialized + int& raa = ax; // \tcode{raa} is constant-initialized +} +\end{codeblock} +\end{example} + \pnum A variable is \defn{potentially-constant} if it is constexpr or @@ -7454,16 +7925,43 @@ \item $V$ is not initialized to a TU-local value, or \item $P$ is in the same translation unit as $D$. \end{itemize} -An object or reference is \defn{usable in constant expressions} if it is +An object or reference is +\defn{potentially usable in constant expressions} at point $P$ if it is \begin{itemize} -\item a variable that is usable in constant expressions, or -\item a template parameter object\iref{temp.param}, or -\item a string literal object\iref{lex.string}, or -\item a temporary object of non-volatile const-qualified literal type - whose lifetime is extended\iref{class.temporary} - to that of a variable that is usable in constant expressions, or -\item a non-mutable subobject or reference member of any of the above. +\item +the object or reference declared by a variable +that is usable in constant expressions at $P$, +\item +a temporary object of non-volatile const-qualified literal type +whose lifetime is extended\iref{class.temporary} +to that of a variable that is usable in constant expressions at $P$, +\item +a template parameter object\iref{temp.param}, +\item +a string literal object\iref{lex.string}, +\item +a non-mutable subobject of any of the above, or +\item +a reference member of any of the above. \end{itemize} +An object or reference is \defn{usable in constant expressions} at point $P$ +if it is an object or reference +that is potentially usable in constant expressions at $P$ and +is constexpr-representable at $P$. +\begin{example} +\begin{codeblock} +struct A { + int* const & r; +}; +void f(int x) { + constexpr A a = {&x}; + static_assert(a.r == &x); // OK + [&] { + static_assert(a.r != nullptr); // error: \tcode{a.r} is not usable in constant expressions at this point + }(); +} +\end{codeblock} +\end{example} \pnum An expression $E$ is a \defnadj{core constant}{expression} @@ -7522,8 +8020,7 @@ \item an operation that would have undefined or erroneous behavior -as specified in \ref{intro} through \ref{cpp}, -excluding \ref{dcl.attr.assume} and \ref{dcl.attr.noreturn}; +as specified in \ref{intro} through \ref{\lastcorechapter}; \begin{footnote} This includes, for example, signed integer overflow\iref{expr.pre}, certain @@ -7535,6 +8032,9 @@ an lvalue-to-rvalue conversion\iref{conv.lval} unless it is applied to \begin{itemize} + \item + a glvalue of type \cv{}~\tcode{std::nullptr_t}, + \item a non-volatile glvalue that refers to an object that is usable in constant expressions, or @@ -7579,7 +8079,8 @@ \begin{note} If the odr-use occurs in an invocation of a function call operator of a closure type, -it no longer refers to \keyword{this} or to an enclosing automatic variable +it no longer refers to \keyword{this} or to an enclosing +variable with automatic storage duration due to the transformation\iref{expr.prim.lambda.capture} of the \grammarterm{id-expression} into an access of the corresponding data member. @@ -7601,13 +8102,15 @@ from a prvalue \tcode{P} of type ``pointer to \cv{}~\keyword{void}'' to a type ``\cvqual{cv1} pointer to \tcode{T}'', where \tcode{T} is not \cvqual{cv2}~\keyword{void}, -unless \tcode{P} points to an object whose type is similar to \tcode{T}; +unless \tcode{P} +is a null pointer value or +points to an object whose type is similar to \tcode{T}; \item a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}; \item -a modification of an object\iref{expr.ass,expr.post.incr,expr.pre.incr} +a modification of an object\iref{expr.assign,expr.post.incr,expr.pre.incr} unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of $E$; @@ -7619,9 +8122,27 @@ \item a \grammarterm{new-expression}\iref{expr.new}, -unless the selected allocation function is +unless either +\begin{itemize} +\item +the selected allocation function is a replaceable global allocation function\iref{new.delete.single,new.delete.array} and -the allocated storage is deallocated within the evaluation of $E$; +the allocated storage is deallocated within the evaluation of $E$, or +\item +the selected allocation function is +a non-allocating form\iref{new.delete.placement} +with an allocated type \tcode{T}, where +\begin{itemize} +\item +the placement argument to the \grammarterm{new-expression} points to +an object whose type is similar to \tcode{T}\iref{conv.qual} or, +if \tcode{T} is an array type, +to the first element of an object of a type similar to \tcode{T}, and +\item +the placement argument points to storage +whose duration began within the evaluation of $E$; +\end{itemize} +\end{itemize} \item a \grammarterm{delete-expression}\iref{expr.delete}, @@ -7639,6 +8160,13 @@ unless it deallocates a region of storage allocated within the evaluation of $E$; +\item +a construction of an exception object, +unless the exception object and +all of its implicit copies created by invocations of +\tcode{std::current_exception} or \tcode{std::rethrow_exception}\iref{propagation} +are destroyed within the evaluation of $E$; + \item an \grammarterm{await-expression}\iref{expr.await}; @@ -7650,21 +8178,24 @@ relational\iref{expr.rel}, or equality\iref{expr.eq} operator where the result is unspecified; -\item -a \grammarterm{throw-expression}\iref{expr.throw}; - \item a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression on a glvalue that refers to an object -whose dynamic type is constexpr-unknown or -that would throw an exception; +whose dynamic type is constexpr-unknown; + +\item +a \tcode{dynamic_cast}\iref{expr.dynamic.cast} expression, +\tcode{typeid}\iref{expr.typeid} expression, or +\tcode{new-expression}\iref{expr.new} +that would throw an exception +where no definition of the exception type is reachable; \item an \grammarterm{asm-declaration}\iref{dcl.asm}; \item -an invocation of the \tcode{va_arg} macro\iref{cstdarg.syn}; +an invocation of the \libmacro{va_arg} macro\iref{cstdarg.syn}; \item a non-constant library call\iref{defns.nonconst.libcall}; @@ -7673,13 +8204,20 @@ \item a \keyword{goto} statement\iref{stmt.goto}. \begin{note} -A \keyword{goto} statement introduced by equivalence\iref{stmt.stmt} +A \keyword{goto} statement introduced by equivalence\iref{stmt} is not in scope. For example, a \keyword{while} statement\iref{stmt.while} can be executed during constant evaluation. \end{note} \end{itemize} +\pnum +It is +\impldef{whether an expression is a core constant expression} +whether $E$ is a core constant expression +if $E$ satisfies the constraints of a core constant expression, but +evaluation of $E$ has runtime-undefined behavior. + \pnum It is unspecified whether $E$ is a core constant expression if $E$ satisfies the constraints of a core constant expression, but @@ -7687,27 +8225,12 @@ \begin{itemize} \item an operation that has undefined behavior -as specified in \ref{library} through \ref{\lastlibchapter}, -\item -an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}, +as specified in \ref{library} through \ref{\lastlibchapter} or \item -a call to a function -that was previously declared -with the \tcode{noreturn} attribute\iref{dcl.attr.noreturn} and -that call returns to its caller, or -\item -a statement with an assumption\iref{dcl.attr.assume} -whose converted \grammarterm{conditional-expression}, -if evaluated where the assumption appears, -would not disqualify $E$ from being a core constant expression and -would not evaluate to \tcode{true}. -\begin{note} -$E$ is not disqualified from being a core constant expression -if the hypothetical evaluation of -the converted \grammarterm{conditional-expression} -would disqualify $E$ from being a core constant expression. -\end{note} +an invocation of the \libmacro{va_start} macro\iref{cstdarg.syn}. \end{itemize} + +\pnum \begin{example} \begin{codeblock} int x; // not constant @@ -7754,14 +8277,6 @@ the evaluation of the body of a member function of \tcode{std::allocator} as defined in \ref{allocator.members}, where \tcode{T} is a literal type, is ignored. -Similarly, the evaluation of the body of -\tcode{std::construct_at} or -\tcode{std::ranges::construct_at} -is considered to include only -the initialization of the \tcode{T} object -if the first argument (of type \tcode{T*}) points -to storage allocated with \tcode{std::allocator} or -to an object whose lifetime began within the evaluation of $E$. \pnum For the purposes of determining whether $E$ is a core constant expression, @@ -7772,6 +8287,45 @@ The copy/move of the active member is trivial. \end{note} +\pnum +For the purposes of determining whether $E$ is a core constant expression, +the evaluation of an \grammarterm{id-expression} +that names a structured binding \tcode{v}\iref{dcl.struct.bind} has the +following semantics: +\begin{itemize} +\item +If \tcode{v} is an lvalue referring to the object bound to an invented reference \tcode{r}, +the behavior is as if \tcode{r} were nominated. +\item +Otherwise, if \tcode{v} names an array element or class member, +the behavior is that of +evaluating \tcode{$e$[$i$]} or \tcode{$e$.$m$}, respectively, +where $e$ is the name of the variable +initialized from the initializer of the structured binding declaration, and +$i$ is the index of the element referred to by \tcode{v} or +$m$ is the name of the member referred to by \tcode{v}, respectively. +\end{itemize} +\begin{example} +\begin{codeblock} +#include +struct S { + mutable int m; + constexpr S(int m): m(m) {} + virtual int g() const; +}; +void f(std::tuple t) { + auto [r] = t; + static_assert(r.g() >= 0); // error: dynamic type is constexpr-unknown + constexpr auto [m] = S(1); + static_assert(m == 1); // error: lvalue-to-rvalue conversion on mutable + // subobject \tcode{e.m}, where \tcode{e} is a constexpr object of type \tcode{S} + using A = int[2]; + constexpr auto [v0, v1] = A{2, 3}; + static_assert(v0 + v1 == 5); // OK, equivalent to \tcode{e[0] + e[1]} where \tcode{e} is a constexpr array +} +\end{codeblock} +\end{example} + \pnum During the evaluation of an expression $E$ as a core constant expression, all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}} @@ -7842,13 +8396,13 @@ \end{example} \pnum -An object \tcode{a} is said to have \defnadj{constant}{destruction} if: +An object \tcode{a} is said to have \defnadj{constant}{destruction} if \begin{itemize} \item it is not of class type nor (possibly multidimensional) array thereof, or \item it is of class type or (possibly multidimensional) array thereof, - that class type has a constexpr destructor, and + that class type has a constexpr destructor\iref{dcl.constexpr}, and for a hypothetical expression $E$ whose only effect is to destroy \tcode{a}, $E$ would be a core constant expression @@ -7915,7 +8469,7 @@ expressions\iref{expr.new}, as case expressions\iref{stmt.switch}, as enumerator initializers if the underlying type is fixed\iref{dcl.enum}, as array bounds\iref{dcl.array}, and -as non-type template +as constant template arguments\iref{temp.arg}. \end{note} \indextext{contextually converted constant expression of type \tcode{bool}|see{conversion, contextual}}% @@ -7928,40 +8482,20 @@ \pnum A \defnadj{constant}{expression} is either a glvalue core constant expression that refers to -an entity that is a permitted result of a constant expression (as defined below), or -a prvalue core constant expression whose value +an object or a non-immediate function, or +a prvalue core constant expression whose result object\iref{basic.lval} satisfies the following constraints: \begin{itemize} - \item - if the value is an object of class type, - each non-static data member of reference type refers to - an entity that is a permitted result of a constant expression, - - \item - if the value is an object of scalar type, - 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, - or a null pointer value, - - \item - if the value is of pointer-to-member-function type, - it does not designate an immediate function, and - - \item - if the value is an object of class or array type, - each subobject satisfies these constraints for the value. +\item +each constituent reference refers to an object or a non-immediate function, +\item +no constituent value of scalar type is an indeterminate or erroneous value\iref{basic.indet}, +\item +no constituent value of pointer type is a pointer to an immediate function or +an invalid pointer value\iref{basic.compound}, and +\item +no constituent value of pointer-to-member type designates an immediate function. \end{itemize} -An entity is a -\defnx{permitted result of a constant expression}{constant expression!permitted result of} -if it is an -object with static storage duration that either is not a temporary object or is -a temporary object whose value satisfies the above constraints, or if -it is a non-immediate function. \begin{note} A glvalue core constant expression that either refers to or points to an unspecified object @@ -8136,6 +8670,15 @@ constexpr int k(int) { // \tcode{k} is not an immediate function because \tcode{A(42)} is a return A(42).y; // constant expression and thus not immediate-escalating } + +constexpr int l(int c) pre(c >= 2) { + return (c % 2 == 0) ? c / 0 : c; +} + +const int i0 = l(0); // dynamic initialization; contract violation or undefined behavior +const int i1 = l(1); // static initialization; value of \tcode{1} or contract violation at compile time +const int i2 = l(2); // dynamic initialization; undefined behavior +const int i3 = l(3); // static initialization; value of \tcode{3} \end{codeblock} \end{example} @@ -8154,7 +8697,10 @@ has constant initialization\iref{basic.start.static}. \begin{footnote} Testing this condition -can involve a trial evaluation of its initializer as described above. +can involve a trial evaluation of its initializer, +with evaluations of contract assertions +using the ignore evaluation semantic\iref{basic.contract.eval}, +as described above. \end{footnote} \begin{example} \begin{codeblock} diff --git a/source/future.tex b/source/future.tex index 04ed0e5eee..50edea0be7 100644 --- a/source/future.tex +++ b/source/future.tex @@ -4,8 +4,8 @@ \rSec1[depr.general]{General} \pnum -This Annex describes features of the \Cpp{} Standard that are specified for compatibility with -existing implementations. +This Annex describes features of this document +that are specified for compatibility with existing implementations. \pnum These are deprecated features, where @@ -16,6 +16,26 @@ An implementation may declare library names and entities described in this Clause with the \tcode{deprecated} attribute\iref{dcl.attr.deprecated}. +\rSec1[depr.local]{Non-local use of TU-local entities} + +\pnum +A declaration of a non-TU-local entity that is an exposure\iref{basic.link} +is deprecated. +\begin{note} +Such a declaration in an importable module unit is ill-formed. +\end{note} +\begin{example} +\begin{codeblock} +namespace { + struct A { + void f() {} + }; +} +A h(); // deprecated: not internal linkage +inline void g() {A().f();} // deprecated: inline and not internal linkage +\end{codeblock} +\end{example} + \rSec1[depr.capture.this]{Implicit capture of \tcode{*this} by reference} \pnum @@ -35,25 +55,6 @@ \end{codeblock} \end{example} -\rSec1[depr.array.comp]{Array comparisons} - -\pnum -Equality and relational comparisons\iref{expr.eq,expr.rel} -between two operands of array type -are deprecated. -\begin{note} -Three-way comparisons\iref{expr.spaceship} between such operands are ill-formed. -\end{note} -\begin{example} -\begin{codeblock} -int arr1[5]; -int arr2[5]; -bool same = arr1 == arr2; // deprecated, same as \tcode{\&arr1[0] == \&arr2[0]}, - // does not compare array contents -auto cmp = arr1 <=> arr2; // error -\end{codeblock} -\end{example} - \rSec1[depr.volatile.type]{Deprecated \tcode{volatile} types} \pnum @@ -72,7 +73,7 @@ \pnum Certain assignments where the left operand is a volatile-qualified non-class type -are deprecated; see~\ref{expr.ass}. +are deprecated; see~\ref{expr.assign}. \begin{example} \begin{codeblock} @@ -114,41 +115,17 @@ \end{codeblock} \end{example} +\rSec1[depr.ellipsis.comma]{Non-comma-separated ellipsis parameters} -\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} - -\pnum -For compatibility with prior revisions of \Cpp{}, a \keyword{constexpr} -static data member may be redundantly redeclared outside the class with no -initializer\iref{basic.def,class.static.data}. -This usage is deprecated. -\begin{example} -\begin{codeblock} -struct A { - static constexpr int n = 5; // definition (declaration in \CppXIV{}) -}; - -constexpr int A::n; // redundant declaration (definition in \CppXIV{}) -\end{codeblock} -\end{example} - -\rSec1[depr.local]{Non-local use of TU-local entities} - -\pnum -A declaration of a non-TU-local entity that is an exposure\iref{basic.link} -is deprecated. -\begin{note} -Such a declaration in an importable module unit is ill-formed. -\end{note} +A \grammarterm{parameter-declaration-clause} +of the form +\grammarterm{parameter-declaration-list} \tcode{...} +is deprecated\iref{dcl.fct}. \begin{example} \begin{codeblock} -namespace { - struct A { - void f() {} - }; -} -A h(); // deprecated: not internal linkage -inline void g() {A().f();} // deprecated: inline and not internal linkage +void f(int...); // deprecated +void g(auto...); // OK, declares a function parameter pack +void h(auto......); // deprecated \end{codeblock} \end{example} @@ -166,12 +143,29 @@ It is possible that future versions of \Cpp{} will specify that these implicit definitions are deleted\iref{dcl.fct.def.delete}. +\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} + +\pnum +For compatibility with prior revisions of \Cpp{}, a \keyword{constexpr} +static data member may be redundantly redeclared outside the class with no +initializer\iref{basic.def,class.static.data}. +This usage is deprecated. +\begin{example} +\begin{codeblock} +struct A { + static constexpr int n = 5; // definition (declaration in \CppXIV{}) +}; + +constexpr int A::n; // redundant declaration (definition in \CppXIV{}) +\end{codeblock} +\end{example} + \rSec1[depr.lit]{Literal operator function declarations using an identifier} \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. @@ -187,13 +181,12 @@ \pnum The following type is defined in addition to those specified in \libheaderref{limits}: -\indexlibraryglobal{float_denorm_style}% \begin{codeblock} namespace std { - enum float_denorm_style { - denorm_indeterminate = -1, - denorm_absent = 0, - denorm_present = 1 + enum @\libglobal{float_denorm_style}@ { + @\libmember{denorm_indeterminate}{float_denorm_style}@ = -1, + @\libmember{denorm_absent}{float_denorm_style}@ = 0, + @\libmember{denorm_present}{float_denorm_style}@ = 1 }; } \end{codeblock} @@ -227,118 +220,28 @@ \rSec1[depr.c.macros]{Deprecated C macros} \pnum -The header \libheader{stdalign.h} has the following macro: -\indexheader{stdalign.h}% -\indexlibraryglobal{__alignas_is_defined}% -\begin{codeblock} -#define @\xname{alignas_is_defined}@ 1 -#define @\xname{alignof_is_defined}@ 1 -\end{codeblock} - -\pnum -The header \libheader{stdbool.h} has the following macro: -\indexheader{stdbool.h}% -\indexhdr{stdbool.h}% -\indexlibraryglobal{__bool_true_false_are_defined}% +The header \libheaderref{stdalign.h} has the following macros: \begin{codeblock} -#define @\xname{bool_true_false_are_defined}@ 1 +#define @\libxmacro{alignas_is_defined}@ 1 +#define @\libxmacro{alignof_is_defined}@ 1 \end{codeblock} -\rSec1[depr.relops]{Relational operators}% -\indexlibraryglobal{rel_ops}% - \pnum -The header \libheaderref{utility} has the following additions: - +The header \libheaderref{stdbool.h} has the following macro: \begin{codeblock} -namespace std::rel_ops { - template bool operator!=(const T&, const T&); - template bool operator> (const T&, const T&); - template bool operator<=(const T&, const T&); - template bool operator>=(const T&, const T&); -} +#define @\libxmacro{bool_true_false_are_defined}@ 1 \end{codeblock} -\pnum -To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} -and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, -the library provides the following: - -\indexlibrary{\idxcode{operator"!=}}% -\begin{itemdecl} -template bool operator!=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{EqualityComparable} requirements (\tref{cpp17.equalitycomparable}). - -\pnum -\returns -\tcode{!(x == y)}. -\end{itemdescr} - -\indexlibraryglobal{operator>}% -\begin{itemdecl} -template bool operator>(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{y < x}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator<=}}% -\begin{itemdecl} -template bool operator<=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{!(y < x)}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator>=}}% -\begin{itemdecl} -template bool operator>=(const T& x, const T& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). - -\pnum -\returns -\tcode{!(x < y)}. -\end{itemdescr} - \rSec1[depr.cerrno]{Deprecated error numbers} \pnum -The following macros are defined in addition to those -specified in \ref{cerrno.syn}: +The header \libheaderref{cerrno} has the following additional macros: -\indexlibraryglobal{ENODATA}% -\indexlibraryglobal{ENOSR}% -\indexlibraryglobal{ENOSTR}% -\indexlibraryglobal{ETIME}% \begin{codeblock} -#define ENODATA @\seebelow@ -#define ENOSR @\seebelow@ -#define ENOSTR @\seebelow@ -#define ETIME @\seebelow@ +#define @\libmacro{ENODATA}@ @\seebelow@ +#define @\libmacro{ENOSR}@ @\seebelow@ +#define @\libmacro{ENOSTR}@ @\seebelow@ +#define @\libmacro{ETIME}@ @\seebelow@ \end{codeblock} \pnum @@ -349,10 +252,10 @@ in addition to those specified in \ref{system.error.syn}: \begin{codeblock} -no_message_available, // \tcode{ENODATA} -no_stream_resources, // \tcode{ENOSR} -not_a_stream, // \tcode{ENOSTR} -stream_timeout, // \tcode{ETIME} +@\libmember{no_message_available}{errc}@, // \tcode{ENODATA} +@\libmember{no_stream_resources}{errc}@, // \tcode{ENOSR} +@\libmember{not_a_stream}{errc}@, // \tcode{ENOSTR} +@\libmember{stream_timeout}{errc}@, // \tcode{ETIME} \end{codeblock} \pnum @@ -368,6 +271,8 @@ \begin{codeblock} namespace std { + template struct is_trivial; + template constexpr bool is_trivial_v = is_trivial::value; template struct is_pod; template constexpr bool is_pod_v = is_pod::value; template // \seebelow @@ -386,6 +291,17 @@ any of the templates defined in this subclause is undefined, unless explicitly permitted by the specification of the corresponding template. +\pnum +\label{term.trivial.type}% +A \defnadj{trivial}{class} is a class that is trivially copyable and +has one or more eligible default constructors, all of which are trivial. +\begin{note} +In particular, +a trivial class does not have virtual functions or virtual base classes. +\end{note} +A \defnadj{trivial}{type} is a scalar type, a trivial class, +an array of such a type, or a cv-qualified version of one of these types. + \pnum \indextext{POD}% A \term{POD class} is a class that is both a trivial class and a @@ -393,6 +309,30 @@ (or array thereof). A \term{POD type} is a scalar type, a POD class, an array of such a type, or a cv-qualified version of one of these types. +\indexlibraryglobal{is_trivial}% +\begin{itemdecl} +template struct is_trivial; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{remove_all_extents_t} shall be a complete type or \cv{} \keyword{void}. + +\pnum +\remarks +\tcode{is_trivial} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} +with a base characteristic of \tcode{true_type} +if \tcode{T} is a trivial type, +and \tcode{false_type} otherwise. + +\pnum +\begin{note} +It is unspecified +whether a closure type\iref{expr.prim.lambda.closure} is a trivial type. +\end{note} +\end{itemdescr} + \indexlibraryglobal{is_pod}% \begin{itemdecl} template struct is_pod; @@ -484,6 +424,86 @@ whose value is the strictest alignment of all types listed in \tcode{Types}. \end{itemdescr} +\rSec1[depr.relops]{Relational operators}% +\indexlibraryglobal{rel_ops}% + +\pnum +The header \libheaderref{utility} has the following additions: + +\begin{codeblock} +namespace std::rel_ops { + template bool operator!=(const T&, const T&); + template bool operator> (const T&, const T&); + template bool operator<=(const T&, const T&); + template bool operator>=(const T&, const T&); +} +\end{codeblock} + +\pnum +To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} +and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, +the library provides the following: + +\indexlibrary{\idxcode{operator"!=}}% +\begin{itemdecl} +template bool operator!=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{EqualityComparable} requirements (\tref{cpp17.equalitycomparable}). + +\pnum +\returns +\tcode{!(x == y)}. +\end{itemdescr} + +\indexlibraryglobal{operator>}% +\begin{itemdecl} +template bool operator>(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{y < x}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator<=}}% +\begin{itemdecl} +template bool operator<=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator>=}}% +\begin{itemdecl} +template bool operator>=(const T& x, const T& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{!(x < y)}. +\end{itemdescr} + \rSec1[depr.tuple]{Tuple} \pnum @@ -675,40 +695,12 @@ \tcode{current}. \end{itemdescr} -\rSec1[depr.format]{Deprecated formatting} - -\rSec2[depr.format.syn]{Header \tcode{} synopsis} - -\pnum -The header \libheaderref{format}{format.syn} has the following additions: - -\begin{codeblock} -namespace std { - template - decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); -} -\end{codeblock} - -\rSec2[depr.format.arg]{Formatting arguments} - -\indexlibraryglobal{visit_format_arg}% -\begin{itemdecl} -template - decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} -\end{itemdescr} - \rSec1[depr.locale.category]{Deprecated locale category facets} \pnum The \tcode{ctype} locale category includes the following facets as if they were specified -in table \tref{locale.category.facets} of \ref{locale.category}. +in \tref{locale.category.facets} of \ref{locale.category}. \begin{codeblock} codecvt @@ -720,7 +712,7 @@ \pnum The \tcode{ctype} locale category includes the following facets as if they were specified -in table \tref{locale.spec} of \ref{locale.category}. +in \tref{locale.spec} of \ref{locale.category}. \begin{codeblock} codecvt_byname @@ -742,6 +734,34 @@ \tcode{codecvt} convert between the UTF-32 and UTF-8 encoding forms. +\rSec1[depr.format]{Deprecated formatting} + +\rSec2[depr.format.syn]{Header \tcode{} synopsis} + +\pnum +The header \libheaderref{format} has the following additions: + +\begin{codeblock} +namespace std { + template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); +} +\end{codeblock} + +\rSec2[depr.format.arg]{Formatting arguments} + +\indexlibraryglobal{visit_format_arg}% +\begin{itemdecl} +template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} +\end{itemdescr} + \rSec1[depr.fs.path.factory]{Deprecated filesystem path factory functions} \pnum @@ -834,8 +854,11 @@ void atomic_init(volatile atomic*, typename atomic::value_type) noexcept; template void atomic_init(atomic*, typename atomic::value_type) noexcept; + template + constexpr T kill_dependency(T y) noexcept; // freestanding + inline constexpr memory_order memory_order_consume = memory_order::consume; // freestanding - #define ATOMIC_VAR_INIT(value) @\seebelow@ + #define @\libmacro{ATOMIC_VAR_INIT}@(value) @\seebelow@ } \end{codeblock} @@ -884,13 +907,13 @@ \indexlibraryglobal{ATOMIC_VAR_INIT}% \begin{itemdecl} -#define ATOMIC_VAR_INIT(value) @\seebelow@ +#define @\libmacro{ATOMIC_VAR_INIT}@(value) @\seebelow@ \end{itemdecl} \begin{itemdescr} \pnum The macro expands to a token sequence suitable for constant initialization of -an atomic variable of static storage duration of a type that +an atomic variable with static storage duration of a type that is initialization-compatible with \tcode{value}. \begin{note} This operation possibly needs to initialize locks. @@ -904,3 +927,25 @@ \end{codeblock} \end{example} \end{itemdescr} + +\rSec2[depr.atomics.order]{\tcode{memory_order::consume}} + +\indexlibraryglobal{memory_order}% +\indexlibrarymember{consume}{memory_order}% +\pnum +The \tcode{memory_order} enumeration contains an additional enumerator: +\begin{codeblock} +consume = 1 +\end{codeblock} +The \tcode{memory_order::consume} enumerator is allowed wherever +\tcode{memory_order::acquire} is allowed, and it has the same meaning. + +\begin{itemdecl} +template constexpr T kill_dependency(T y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{y}. +\end{itemdescr} diff --git a/source/grammar.tex b/source/grammar.tex index 8501d39453..db27a2f510 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -58,4 +58,4 @@ identifier \end{ncbnf} -\FlushAndPrintGrammar +\input{std-gram.ext} diff --git a/source/intro.tex b/source/intro.tex index 2058956582..75705a2bab 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -36,18 +36,18 @@ \item ISO/IEC 2382, \doccite{Information technology --- Vocabulary} \item ISO 8601-1:2019, \doccite{Date and time --- Representations for information interchange --- Part 1: Basic rules} \item \IsoC{}, \doccite{Information technology --- Programming languages --- C} -\item ISO/IEC/IEEE 9945:2009, \doccite{Information Technology --- Portable Operating System Interface\begin{footnote} +\item \IsoPosix{}, \doccite{Information Technology --- Portable Operating System Interface (POSIX\textregistered)\begin{footnote} POSIX\textregistered\ is a registered trademark of the Institute of Electrical and Electronic Engineers, Inc. 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}% -(POSIX\textregistered) Base Specifications, Issue 7} -\item ISO/IEC/IEEE 9945:2009/Cor 1:2013, \doccite{Information Technology --- Portable Operating System Interface +\end{footnote} +Base Specifications, Issue 7} +\item \IsoPosix{}/Cor 1:2013, \doccite{Information Technology --- Portable Operating System Interface (POSIX\textregistered) Base Specifications, Issue 7 --- Technical Corrigendum 1} -\item ISO/IEC/IEEE 9945:2009/Cor 2:2017, \doccite{Information Technology --- Portable Operating System Interface +\item \IsoPosix{}/Cor 2:2017, \doccite{Information Technology --- Portable Operating System Interface (POSIX\textregistered) Base Specifications, Issue 7 --- Technical Corrigendum 2} -\item ISO/IEC 60559:2020, \doccite{Information technology --- Microprocessor Systems --- Floating-Point arithmetic} +\item \IsoFloatUndated{}:2020, \doccite{Information technology --- Microprocessor Systems --- Floating-Point arithmetic} \item ISO 80000-2:2019, \doccite{Quantities and units --- Part 2: Mathematics} % Other international standards. \item Ecma International, \doccite{ECMAScript @@ -89,10 +89,10 @@ read or modify the value of an object \begin{defnote} -Only glvalues of scalar type can be used to access objects. +Only glvalues of scalar type\iref{basic.types.general} can be used to access objects. Reads of scalar objects are described in \ref{conv.lval} and modifications of scalar objects are described in -\ref{expr.ass}, \ref{expr.post.incr}, and \ref{expr.pre.incr}. +\ref{expr.assign}, \ref{expr.post.incr}, and \ref{expr.pre.incr}. Attempts to read or modify an object of class type typically invoke a constructor\iref{class.ctor} or assignment operator\iref{class.copy.assign}; @@ -103,8 +103,9 @@ \indexdefn{argument}% \indexdefn{argument!function call expression} \definition{argument}{defns.argument} -\defncontext{function call expression} expression in the -comma-separated list bounded by the parentheses +\defncontext{function call expression} +expression or \grammarterm{braced-init-list} +in the comma-separated list bounded by the parentheses \indexdefn{argument}% \indexdefn{argument!function-like macro}% @@ -206,6 +207,11 @@ constructs that it does not support. \end{defnote} +\definition{constant evaluation}{defns.const.eval} +\indexdefn{constant evaluation}% +evaluation that is performed as part of evaluating an expression +as a core constant expression\iref{expr.const} + \definition{constant subexpression}{defns.const.subexpr} \indexdefn{constant subexpression}% expression whose evaluation as subexpression of a @@ -248,6 +254,7 @@ \definition{dynamic type}{defns.dynamic.type.prvalue} \defncontext{prvalue} \termref{defns.static.type}{static type}{} of the prvalue expression +\indexdefn{behavior!erroneous}% \definition{erroneous behavior}{defns.erroneous} well-defined behavior that the implementation is recommended to diagnose \begin{defnote} @@ -255,7 +262,7 @@ Implementations are allowed, but not required, to diagnose it\iref{intro.compliance.general}. Evaluation of a constant expression\iref{expr.const} -never exhibits behavior specified as erroneous in \ref{intro} through \ref{cpp}. +never exhibits behavior specified as erroneous in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} \definition{expression-equivalent}{defns.expression.equivalent} @@ -291,7 +298,7 @@ \definition{format specifier}{defns.regex.format.specifier} \defncontext{regular expression} \indexdefn{format specifier}% -sequence of one or more \termref{defns.character}{character}{s} that is to be +sequence of one or more \termref{defns.character}{character}{s} that is expected to be replaced with some part of a \termref{defns.regex.regular.expression}{regular expression}{} match \definition{handler function}{defns.handler} @@ -302,7 +309,7 @@ \begin{defnote} A \Cpp{} program may designate a handler function at various points in its execution by supplying a pointer to the function when calling any of the library functions that install -handler functions\iref{support}. +handler functions (see \ref{support}). \end{defnote} \indexdefn{program!ill-formed}% @@ -411,7 +418,7 @@ set of one or more \termref{defns.character}{character}{s} which share the same primary sort key: that is the sort key weighting that depends only upon character shape, and not accents, case, or -locale specific tailorings +locale-specific tailorings \definition{program-defined specialization}{defns.prog.def.spec} \defncontext{library} @@ -503,6 +510,23 @@ \indextext{undefined} \end{defnote} +\definition{runtime-undefined behavior}{defns.undefined.runtime} +\indexdefn{behavior!runtime-undefined}% +behavior that is undefined except when it occurs during constant evaluation + +\begin{defnote} +During constant evaluation, +\begin{itemize} +\item +it is +\impldef{whether runtime-undefined behavior results in the expression being deemed non-constant} +whether runtime-undefined behavior results in the expression being deemed non-constant +(as specified in~\ref{expr.const}) and +\item +runtime-undefined behavior has no other effect. +\end{itemize} +\end{defnote} + \indexdefn{signature}% \definition{signature}{defns.signature} \defncontext{function} @@ -624,7 +648,7 @@ \indexdefn{unblock}% \definition{unblock}{defns.unblock} -satisfy a condition that one or more \termref{defns.block}{block}{ed} threads of execution are waiting for +satisfy a condition that one or more \termref{defns.block}{blocked}{} threads of execution are waiting for \indexdefn{behavior!undefined}% \definition{undefined behavior}{defns.undefined} @@ -643,7 +667,7 @@ issuance of a diagnostic message). Many incorrect program constructs do not engender undefined behavior; they are required to be diagnosed. Evaluation of a constant expression\iref{expr.const} never exhibits behavior explicitly -specified as undefined in \ref{intro} through \ref{cpp}. +specified as undefined in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} \indexdefn{behavior!unspecified}% @@ -721,16 +745,15 @@ \begin{itemize} \item If a program contains no violations of the rules in -\ref{lex} through \ref{\lastlibchapter} and \ref{depr}, -a conforming implementation shall, -within its resource limits as described in \ref{implimits}, -accept and correctly execute +\ref{lex} through \ref{\lastlibchapter} as well as those specified in \ref{depr}, +a conforming implementation shall accept and correctly execute \begin{footnote} ``Correct execution'' can include undefined behavior and erroneous behavior, depending on the data being processed; see \ref{intro.defs} and~\ref{intro.execution}. \end{footnote} -that program. +that program, +except when the implementation's limitations (see below) are exceeded. \item \indextext{behavior!undefined}% If a program contains a violation of a rule for which no diagnostic is required, @@ -739,17 +762,24 @@ \item \indextext{message!diagnostic}% +\indextext{contract evaluation semantics!checking}% +\indextext{contract evaluation semantics!terminating}% Otherwise, if a program contains \begin{itemize} \item a violation of any diagnosable rule, \item a preprocessing translation unit with -a \tcode{\#warning} preprocessing directive\iref{cpp.error}, or +a \tcode{\#warning} preprocessing directive\iref{cpp.error}, \item an occurrence of a construct described in this document as ``conditionally-supported'' when -the implementation does not support that construct, +the implementation does not support that construct, or +\item +a contract assertion\iref{basic.contract.eval} +evaluated with a checking semantic +in a manifestly constant-evaluated context \iref{expr.const} +resulting in a contract violation, \end{itemize} a conforming implementation shall issue at least one diagnostic message. @@ -765,10 +795,14 @@ \begin{itemize} \item a preprocessing translation unit containing -a \tcode{\#error} preprocessing directive\iref{cpp.error} or +a \tcode{\#error} preprocessing directive\iref{cpp.error}, \item a translation unit with -a \grammarterm{static_assert-declaration} that fails\iref{dcl.pre}. +a \grammarterm{static_assert-declaration} that fails\iref{dcl.pre}, or +\item +a contract assertion evaluated with a terminating semantic\iref{basic.contract.eval} +in a manifestly constant-evaluated context\iref{expr.const} +resulting in a contract violation. \end{itemize} \pnum @@ -799,7 +833,8 @@ \indextext{conformance requirements!library|)} \pnum -Two kinds of implementations are defined: a \defnadj{hosted}{implementation} and a +An implementation is either a +\defnadj{hosted}{implementation} or a \defnadj{freestanding}{implementation}. A freestanding implementation is one in which execution may take place without the benefit of @@ -808,9 +843,25 @@ supports all the facilities described in this document, while a freestanding implementation supports the entire \Cpp{} language -described in \ref{lex} through \ref{cpp} and +described in \ref{lex} through \ref{\lastcorechapter} and the subset of the library facilities described in \ref{compliance}. +\pnum +It is +\impldef{whether the implementation is a hardened implementation} +whether the implementation is a +\defnadj{hardened}{implementation}. +If it is a hardened implementation, +violating a hardened precondition +results in a contract violation\iref{structure.specifications}. + +\pnum +An implementation is encouraged to document its limitations in +the size or complexity of the programs it can successfully process, +if possible and where known. +\ref{implimits} lists some quantities that can be subject to limitations and +a potential minimum supported value for each quantity. + \pnum A conforming implementation may have extensions (including additional library functions), provided they do not alter the @@ -889,23 +940,43 @@ Certain other operations are described in this document as undefined behavior (for example, the effect of attempting to modify a const object). + +\pnum +Certain events in the execution of a program +are termed \defnadj{observable}{checkpoints}. \begin{note} -This document imposes no requirements on the -behavior of programs that contain undefined behavior. +A call to \tcode{std::observable}\iref{utility.undefined} +is an observable checkpoint, +as are certain parts of +the evaluation of contract assertions\iref{basic.contract}. \end{note} \pnum \indextext{program!well-formed}% \indextext{behavior!observable}% +The \defnadj{defined}{prefix} of an execution +comprises the operations $O$ +for which for every undefined operation $U$ +there is an observable checkpoint $C$ +such that $O$ happens before $C$ and +$C$ happens before $U$. + +\begin{note} +The undefined behavior that arises from a data race\iref{intro.races} +occurs on all participating threads. +\end{note} + A conforming implementation executing a well-formed program shall -produce the same observable behavior as one of the possible executions -of the corresponding instance of the abstract machine with the +produce the observable behavior +of the defined prefix +of one of the possible executions +of the corresponding instance +of the abstract machine with the same program and the same input. \indextext{behavior!undefined}% -However, if any such execution contains an undefined operation, this document places no -requirement on the implementation executing that program with that input -(not even with regard to operations preceding the first undefined -operation). +If the selected execution contains an undefined operation, +the implementation executing that program with that input +may produce arbitrary additional observable behavior afterwards. If the execution contains an operation specified as having erroneous behavior, the implementation is permitted to issue a diagnostic and is permitted to terminate the execution @@ -923,23 +994,28 @@ \pnum \indextext{conformance requirements}% -The least requirements on a conforming implementation are: +The following specify the +\defnadj{observable}{behavior} +of the program: \begin{itemize} \item Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine. \item -At program termination, all data written into files shall be -identical to one of the possible results that execution of the program -according to the abstract semantics would have produced. +Data is delivered to the host environment to be written into files (\xrefc{7.21.3}). + +\begin{note} +Delivering such data +is followed by an observable checkpoint\iref{cstdio.syn}. +Not all host environments provide access to file contents before program termination. +\end{note} + \item The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input. What constitutes an interactive device is \impldef{interactive device}. \end{itemize} -These collectively are referred to as the -\defnx{observable behavior}{behavior!observable} of the program. \begin{note} More stringent correspondences between abstract and actual semantics can be defined by each implementation. @@ -951,7 +1027,7 @@ \pnum \indextext{standard!structure of|(}% \indextext{standard!structure of}% -\ref{lex} through \ref{cpp} describe the \Cpp{} programming +\ref{lex} through \ref{\lastcorechapter} describe the \Cpp{} programming language. That description includes detailed syntactic specifications in a form described in~\ref{syntax}. For convenience, \ref{gram} repeats all such syntactic specifications. diff --git a/source/iostreams.tex b/source/iostreams.tex index 101e063a36..535596515e 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -86,7 +86,7 @@ It is used to represent the number of characters transferred in an I/O operation, or the size of I/O buffers. \begin{footnote} -Most places where \tcode{streamsize} is used would use \tcode{size_t} in ISO C, +Most places where \tcode{streamsize} is used would use \tcode{size_t} in C, or \tcode{ssize_t} in POSIX. \end{footnote} \end{itemdescr} @@ -480,6 +480,12 @@ declares objects that associate objects with the standard C streams provided for by the functions declared in \libheader{cstdio}, and includes all the headers necessary to use these objects. +The dynamic types of the stream buffers +initially associated with these objects are unspecified, +but they have the behavior specified for +\tcode{std::basic_filebuf} +or +\tcode{std::basic_filebuf}. \pnum The objects are constructed and the associations are established at some @@ -683,11 +689,15 @@ #include // see \ref{iosfwd.syn} namespace std { + // \ref{stream.types}, types using streamoff = @\impdef@; using streamsize = @\impdef@; + // \ref{fpos}, class template \tcode{fpos} template class fpos; + // \ref{ios.base}, class \tcode{ios_base} class ios_base; + // \ref{ios}, class template \tcode{basic_ios} template> class basic_ios; @@ -730,8 +740,8 @@ ios_base& defaultfloat(ios_base& str); // \ref{error.reporting}, error reporting - enum class io_errc { - stream = 1 + enum class @\libglobal{io_errc}@ { + @\libmember{stream}{io_errc}@ = 1 }; template<> struct is_error_code_enum : public true_type { }; @@ -827,7 +837,7 @@ virtual ~ios_base(); // \ref{ios.base.callback}, callbacks - enum event { erase_event, imbue_event, copyfmt_event }; + enum @\libmember{event}{ios_base}@ { erase_event, imbue_event, copyfmt_event }; using event_callback = void (*)(event, ios_base&, int idx); void register_callback(event_callback fn, int idx); @@ -840,9 +850,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} @@ -878,19 +888,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} @@ -1128,9 +1138,6 @@ Init(const Init&) = default; ~Init(); Init& operator=(const Init&) = default; - - private: - static int init_cnt; // \expos }; } \end{codeblock} @@ -1144,17 +1151,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(); @@ -1442,7 +1438,7 @@ \begin{itemdescr} \pnum \returns -\tcode{index} +\exposid{index} \tcode{++}. \pnum @@ -1463,20 +1459,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 @@ -1501,7 +1497,7 @@ \pnum \returns On success -\tcode{iarray[idx]}. +\tcode{\exposid{iarray}[idx]}. On failure, a valid \tcode{long\&} initialized to 0. @@ -1519,13 +1515,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 @@ -1641,6 +1637,8 @@ \rSec2[fpos]{Class template \tcode{fpos}} +\rSec3[fpos.general]{General} + \indexlibraryglobal{fpos}% \begin{codeblock} namespace std { @@ -1651,7 +1649,7 @@ void state(stateT); private: - stateT st; // \expos + stateT @\exposid{st}@; // \expos }; } \end{codeblock} @@ -1666,7 +1664,7 @@ \begin{itemdescr} \pnum \effects -Assigns \tcode{s} to \tcode{st}. +Assigns \tcode{s} to \exposid{st}. \end{itemdescr} \indexlibrarymember{state}{fpos}% @@ -1677,7 +1675,7 @@ \begin{itemdescr} \pnum \returns -Current value of \tcode{st}. +Current value of \exposid{st}. \end{itemdescr} \rSec3[fpos.operations]{Requirements} @@ -2883,6 +2881,7 @@ \indexlibraryglobal{basic_streambuf}% \begin{codeblock} namespace std { + // \ref{streambuf}, class template \tcode{basic_streambuf} template> class basic_streambuf; using streambuf = basic_streambuf; @@ -3643,7 +3642,7 @@ \begin{itemdecl} pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which - = ios_base::in | ios_base::out); + = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -3665,7 +3664,7 @@ \begin{itemdecl} pos_type seekpos(pos_type sp, ios_base::openmode which - = ios_base::in | ios_base::out); + = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} @@ -4147,21 +4146,25 @@ \indexheader{istream}% \begin{codeblock} namespace std { + // \ref{istream}, class template \tcode{basic_istream} template> class basic_istream; using istream = basic_istream; using wistream = basic_istream; + // \ref{iostreamclass}, class template \tcode{basic_iostream} template> class basic_iostream; using iostream = basic_iostream; using wiostream = basic_iostream; + // \ref{istream.manip}, standard \tcode{basic_istream} manipulators template basic_istream& ws(basic_istream& is); + // \ref{istream.rvalue}, rvalue stream extraction template Istream&& operator>>(Istream&& is, T&& x); } @@ -4177,12 +4180,14 @@ \indexheader{ostream}% \begin{codeblock} namespace std { + // \ref{ostream}, class template \tcode{basic_ostream} template> class basic_ostream; using ostream = basic_ostream; using wostream = basic_ostream; + // \ref{ostream.manip}, standard \tcode{basic_ostream} manipulators template basic_ostream& endl(basic_ostream& os); template @@ -4197,6 +4202,7 @@ template basic_ostream& flush_emit(basic_ostream& os); + // \ref{ostream.rvalue}, rvalue stream insertion template Ostream&& operator<<(Ostream&& os, const T& x); @@ -4222,17 +4228,21 @@ \indexheader{iomanip}% \begin{codeblock} namespace std { + // \ref{std.manip}, standard manipulators @\unspec@ resetiosflags(ios_base::fmtflags mask); @\unspec@ setiosflags (ios_base::fmtflags mask); @\unspec@ setbase(int base); template @\unspec@ setfill(charT c); @\unspec@ setprecision(int n); @\unspec@ setw(int n); + + // \ref{ext.manip}, extended manipulators template @\unspec@ get_money(moneyT& mon, bool intl = false); template @\unspec@ put_money(const moneyT& mon, bool intl = false); template @\unspec@ get_time(tm* tmb, const charT* fmt); template @\unspec@ put_time(const tm* tmb, const charT* fmt); + // \ref{quoted.manip}, quoted manipulators template @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); @@ -4270,9 +4280,11 @@ void vprint_unicode(string_view fmt, format_args args); void vprint_unicode(FILE* stream, string_view fmt, format_args args); + void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args); void vprint_nonunicode(string_view fmt, format_args args); void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); + void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args); } \end{codeblock} @@ -4501,12 +4513,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; }; @@ -4603,9 +4615,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 @@ -4640,7 +4652,7 @@ \begin{itemdescr} \pnum \returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec3[istream.formatted]{Formatted input functions} @@ -4936,7 +4948,7 @@ \pnum Characters are extracted and stored until any of the following occurs: \begin{itemize} -\item \tcode{n-1} characters are stored; +\item \tcode{n - 1} characters are stored; \item end of file occurs on the input sequence; \item letting \tcode{ct} be \tcode{use_facet>(in.getloc())}, \tcode{ct.is(ct.space, c)} is \tcode{true}. @@ -5392,7 +5404,7 @@ \item \tcode{n != numeric_limits::max()}\iref{numeric.limits} and -\tcode{n} characters have been extracted so far +\tcode{n} characters have been extracted so far; \item end-of-file occurs on the input sequence (in which case the function calls @@ -6169,12 +6181,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; @@ -6215,9 +6227,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 @@ -6258,7 +6270,7 @@ \pnum \effects Returns -\tcode{ok_}. +\exposid{ok_}. \end{itemdescr} \rSec4[ostream.seeks]{Seek members} @@ -6354,7 +6366,7 @@ \tcode{*this}'s error state. If -\tcode{(exceptions()\&badbit) != 0} +\tcode{(exceptions() \& badbit) != 0} then the exception is rethrown. Whether or not an exception is thrown, the \tcode{sentry} @@ -6426,9 +6438,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 @@ -6436,9 +6447,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(); @@ -6449,9 +6459,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(); @@ -6463,20 +6472,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 @@ -6533,20 +6538,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} @@ -6821,7 +6822,7 @@ \effects Equivalent to: \begin{codeblock} -print(os, "{}\n", format(fmt, std::forward(args)...)); +print(os, "{}\n", format(os.getloc(), fmt, std::forward(args)...)); \end{codeblock} \end{itemdescr} @@ -6859,25 +6860,32 @@ without regard to the value of \tcode{os.exceptions()} and without turning on \tcode{ios_base::badbit} in the error state of \tcode{os}. \end{itemize} + +\par % This paragraph is part of the \effects clause. After constructing a \tcode{sentry} object, -the function initializes an automatic variable via +the function initializes a variable with automatic storage duration via \begin{codeblock} string out = vformat(os.getloc(), fmt, args); \end{codeblock} +\begin{itemize} +\item If the function is \tcode{vprint_unicode} and -\tcode{os} is a stream that refers to a terminal capable of displaying Unicode +\tcode{os} is a stream that refers to a terminal that +is capable of displaying Unicode only via a native Unicode API, which is determined in an implementation-defined manner, +flushes \tcode{os} and then writes \tcode{out} to the terminal using the native Unicode API; if \tcode{out} contains invalid code units, \indextext{undefined}% -the behavior is undefined and -implementations are encouraged to diagnose it. -If the native Unicode API is used, -the function flushes \tcode{os} before writing \tcode{out}. -Otherwise (if \tcode{os} is not such a stream or -the function is \tcode{vprint_nonunicode}), +the behavior is undefined. +Then establishes an observable checkpoint\iref{intro.abstract}. +\item +Otherwise inserts the character sequence \range{out.begin()}{out.end()} into \tcode{os}. +\end{itemize} + +\par % This paragraph is part of the \effects clause. If writing to the terminal or inserting into \tcode{os} fails, calls \tcode{os.setstate(ios_base::badbit)} (which may throw \tcode{ios_base::failure}). @@ -7015,7 +7023,7 @@ \tcode{*this}. \end{itemdescr} -\rSec3[ostream.manip]{Standard manipulators} +\rSec3[ostream.manip]{Standard \tcode{basic_ostream} manipulators} \pnum Each instantiation of any of the function templates @@ -7094,7 +7102,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 @@ -7728,14 +7736,14 @@ If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: \begin{codeblock} locksafe - ? vprint_unicode_locking(stream, fmt.str, make_format_args(args...)) - : vprint_unicode(stream, fmt.str, make_format_args(args...)); + ? vprint_unicode(stream, fmt.str, make_format_args(args...)) + : vprint_unicode_buffered(stream, fmt.str, make_format_args(args...)); \end{codeblock} Otherwise, equivalent to: \begin{codeblock} locksafe - ? vprint_nonunicode_locking(stream, fmt.str, make_format_args(args...)) - : vprint_nonunicode(stream, fmt.str, make_format_args(args...)); + ? vprint_nonunicode(stream, fmt.str, make_format_args(args...)) + : vprint_nonunicode_buffered(stream, fmt.str, make_format_args(args...)); \end{codeblock} \end{itemdescr} @@ -7811,9 +7819,9 @@ \end{codeblock} \end{itemdescr} -\indexlibraryglobal{vprint_unicode}% +\indexlibraryglobal{vprint_unicode_buffered}% \begin{itemdecl} -void vprint_unicode(FILE* stream, string_view fmt, format_args args); +void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} @@ -7822,13 +7830,13 @@ Equivalent to: \begin{codeblock} string out = vformat(fmt, args); -vprint_unicode_locking(stream, "{}", make_format_args(out)); +vprint_unicode(stream, "{}", make_format_args(out)); \end{codeblock} \end{itemdescr} -\indexlibraryglobal{vprint_unicode_locking}% +\indexlibraryglobal{vprint_unicode}% \begin{itemdecl} -void vprint_unicode_locking(FILE* stream, string_view fmt, format_args args); +void vprint_unicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} @@ -7842,28 +7850,28 @@ Let \tcode{out} denote the character representation of formatting arguments provided by \tcode{args} formatted according to specifications given in \tcode{fmt}. -If \tcode{stream} refers to a terminal capable of displaying Unicode, +\begin{itemize} +\item +If \tcode{stream} refers to a terminal that +is capable of displaying Unicode only via a native Unicode API, +flushes \tcode{stream} and then writes \tcode{out} to the terminal using the native Unicode API; if \tcode{out} contains invalid code units, \indextext{undefined}% -the behavior is undefined and -implementations are encouraged to diagnose it. +the behavior is undefined. +Then establishes an observable checkpoint\iref{intro.abstract}. +\item Otherwise writes \tcode{out} to \tcode{stream} unchanged. -If the native Unicode API is used, -the function flushes \tcode{stream} before writing \tcode{out}. +\end{itemize} Unconditionally unlocks \tcode{stream} on function exit. \xrefc{7.21.2}. \begin{note} -On POSIX and Windows, \tcode{stream} referring to a terminal means that, -respectively, -\tcode{isatty(fileno(\linebreak{}stream))} and +On Windows the native Unicode API is \tcode{WriteConsoleW} and +\tcode{stream} referring to a terminal means that \tcode{GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)} -return nonzero. -\end{note} -\begin{note} -On Windows, the native Unicode API is \tcode{WriteConsoleW}. +returns nonzero. \end{note} \pnum @@ -7894,9 +7902,9 @@ \end{codeblock} \end{itemdescr} -\indexlibraryglobal{vprint_nonunicode}% +\indexlibraryglobal{vprint_nonunicode_buffered}% \begin{itemdecl} -void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} @@ -7905,13 +7913,13 @@ Equivalent to: \begin{codeblock} string out = vformat(fmt, args); -vprint_nonunicode_locking("{}", make_format_args(out)); +vprint_nonunicode("{}", make_format_args(out)); \end{codeblock} \end{itemdescr} -\indexlibraryglobal{vprint_nonunicode_locking}% +\indexlibraryglobal{vprint_nonunicode}% \begin{itemdecl} -void vprint_nonunicode_locking(FILE* stream, string_view fmt, format_args args); +void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} @@ -7956,6 +7964,7 @@ \indexlibraryglobal{basic_stringstream}% \begin{codeblock} namespace std { + // \ref{stringbuf}, class template \tcode{basic_stringbuf} template, class Allocator = allocator> class basic_stringbuf; @@ -7967,6 +7976,7 @@ using stringbuf = basic_stringbuf; using wstringbuf = basic_stringbuf; + // \ref{istringstream}, class template \tcode{basic_istringstream} template, class Allocator = allocator> class basic_istringstream; @@ -7978,6 +7988,7 @@ using istringstream = basic_istringstream; using wistringstream = basic_istringstream; + // \ref{ostringstream}, class template \tcode{basic_ostringstream} template, class Allocator = allocator> class basic_ostringstream; @@ -7989,6 +8000,7 @@ using ostringstream = basic_ostringstream; using wostringstream = basic_ostringstream; + // \ref{stringstream}, class template \tcode{basic_stringstream} template, class Allocator = allocator> class basic_stringstream; @@ -8091,15 +8103,15 @@ pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which - = ios_base::in | ios_base::out) override; + = ios_base::in | ios_base::out) override; pos_type seekpos(pos_type sp, ios_base::openmode which - = ios_base::in | ios_base::out) override; + = 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} @@ -8120,17 +8132,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} @@ -8145,7 +8157,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} @@ -8171,9 +8183,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}% @@ -8186,9 +8198,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 @@ -8206,9 +8218,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}% @@ -8223,9 +8235,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}% @@ -8244,9 +8256,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}% @@ -8275,9 +8287,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}% @@ -8290,10 +8302,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 @@ -8398,39 +8410,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} @@ -8444,7 +8456,7 @@ \begin{itemdescr} \pnum \returns -\tcode{buf.get_allocator()}. +\tcode{\exposid{buf}.get_allocator()}. \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% @@ -8491,7 +8503,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 @@ -8517,10 +8529,10 @@ 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}, - then \tcode{sv(pbase(), high_mark-pbase())} is returned. -\item Otherwise, if \tcode{ios_base::in} is set in \tcode{mode}, - then \tcode{sv(eback(), egptr()-eback())} is returned. +\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 \exposid{mode}, + then \tcode{sv(eback(), egptr() - eback())} is returned. \item Otherwise, \tcode{sv()} is returned. \end{itemize} @@ -8542,8 +8554,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8562,8 +8574,8 @@ \effects Equivalent to: \begin{codeblock} -buf = s; -init_buf_ptrs(); +@\exposid{buf}@ = s; +@\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} @@ -8577,8 +8589,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} @@ -8599,8 +8611,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} @@ -8659,7 +8671,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, @@ -8745,14 +8757,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. @@ -8940,7 +8952,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -8956,7 +8968,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} @@ -8970,8 +8982,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} @@ -8986,8 +8998,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} @@ -9000,8 +9012,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} @@ -9016,8 +9028,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} @@ -9033,8 +9045,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} @@ -9054,8 +9066,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} @@ -9082,8 +9094,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}% @@ -9097,7 +9109,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} @@ -9114,7 +9126,7 @@ Equivalent to: \begin{codeblock} basic_istream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9142,7 +9154,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% @@ -9313,7 +9325,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9329,7 +9341,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} @@ -9343,8 +9355,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} @@ -9359,8 +9371,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} @@ -9373,8 +9385,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} @@ -9389,8 +9401,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} @@ -9406,8 +9418,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} @@ -9427,8 +9439,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} @@ -9455,8 +9467,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}% @@ -9470,7 +9482,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} @@ -9487,7 +9499,7 @@ Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9514,7 +9526,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% @@ -9686,7 +9698,7 @@ void str(const T& t); private: - basic_stringbuf sb; // \expos + basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -9703,7 +9715,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} @@ -9717,9 +9729,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} @@ -9735,9 +9747,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} @@ -9751,8 +9763,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} @@ -9767,8 +9779,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} @@ -9784,8 +9796,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} @@ -9805,8 +9817,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} @@ -9833,8 +9845,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}% @@ -9848,7 +9860,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} @@ -9865,7 +9877,7 @@ Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -9892,7 +9904,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% @@ -10002,7 +10014,7 @@ \begin{note} A user of these classes is responsible for ensuring that the character sequence represented by the given \tcode{span} -outlives the use of the sequence by objects of the classes in subclause \ref{span.streams}. +outlives the use of the sequence by objects of the classes in \ref{span.streams}. Using multiple \tcode{basic_spanbuf} objects referring to overlapping underlying sequences from different threads, where at least one \tcode{basic_spanbuf} object is used @@ -10022,6 +10034,7 @@ \indexlibraryglobal{wspanstream}% \begin{codeblock} namespace std { + // \ref{spanbuf}, class template \tcode{basic_spanbuf} template> class basic_spanbuf; @@ -10031,6 +10044,7 @@ using spanbuf = basic_spanbuf; using wspanbuf = basic_spanbuf; + // \ref{ispanstream}, class template \tcode{basic_ispanstream} template> class basic_ispanstream; @@ -10040,6 +10054,7 @@ using ispanstream = basic_ispanstream; using wispanstream = basic_ispanstream; + // \ref{ospanstream}, class template \tcode{basic_ospanstream} template> class basic_ospanstream; @@ -10049,6 +10064,7 @@ using ospanstream = basic_ospanstream; using wospanstream = basic_ospanstream; + // \ref{spanstream}, class template \tcode{basic_spanstream} template> class basic_spanstream; @@ -10106,7 +10122,7 @@ private: ios_base::openmode @\exposid{mode}@; // \expos std::span @\exposid{buf}@; // \expos -}; + }; } \end{codeblock} @@ -10337,7 +10353,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} @@ -10425,7 +10441,7 @@ template void span(ROS&& s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10448,8 +10464,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} @@ -10462,9 +10478,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}% @@ -10501,7 +10517,7 @@ Equivalent to: \begin{codeblock} basic_istream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10529,7 +10545,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10611,7 +10627,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10628,8 +10644,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} @@ -10642,9 +10658,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} @@ -10660,7 +10676,7 @@ Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10688,7 +10704,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10750,7 +10766,7 @@ void span(std::span s) noexcept; private: - basic_spanbuf sb; // \expos + basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -10767,8 +10783,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} @@ -10781,8 +10797,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} @@ -10799,7 +10815,7 @@ Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); -sb.swap(rhs.sb); +@\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} @@ -10827,7 +10843,7 @@ \effects Equivalent to: \begin{codeblock} -return const_cast*>(addressof(sb)); +return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} @@ -10876,6 +10892,7 @@ \indexlibraryglobal{basic_fstream}% \begin{codeblock} namespace std { + // \ref{filebuf}, class template \tcode{basic_filebuf} template> class basic_filebuf; @@ -10885,6 +10902,7 @@ using filebuf = basic_filebuf; using wfilebuf = basic_filebuf; + // \ref{ifstream}, class template \tcode{basic_ifstream} template> class basic_ifstream; @@ -10894,6 +10912,7 @@ using ifstream = basic_ifstream; using wifstream = basic_ifstream; + // \ref{ofstream}, class template \tcode{basic_ofstream} template> class basic_ofstream; @@ -10903,6 +10922,7 @@ using ofstream = basic_ofstream; using wofstream = basic_ofstream; + // \ref{fstream}, class template \tcode{basic_fstream} template> class basic_fstream; @@ -11214,7 +11234,7 @@ \begin{itemdescr} \pnum \expects -\tcode{s} points to a NTCTS\iref{defns.ntcts}. +\tcode{s} points to an NTCTS\iref{defns.ntcts}. \pnum \effects @@ -11559,6 +11579,7 @@ At this point if \tcode{b != p} and \tcode{b == end} (\tcode{xbuf} isn't large enough) then increase \tcode{XSIZE} and repeat from the beginning. \end{itemize} +Then establishes an observable checkpoint\iref{intro.abstract}. \pnum \returns @@ -11802,7 +11823,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -11818,7 +11839,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} @@ -11832,8 +11853,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} @@ -11849,8 +11870,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)}. @@ -11895,7 +11916,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} @@ -11912,7 +11933,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}% @@ -11937,7 +11958,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ifstream}% @@ -12061,7 +12082,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12077,7 +12098,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} @@ -12091,8 +12112,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} @@ -12108,8 +12129,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)}. @@ -12154,7 +12175,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} @@ -12171,7 +12192,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}% @@ -12196,7 +12217,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ofstream}% @@ -12293,7 +12314,7 @@ ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path::value_type* s, - ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} + ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} explicit basic_fstream( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); @@ -12318,7 +12339,7 @@ ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path::value_type* s, - ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} + ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} void open( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); @@ -12328,7 +12349,7 @@ void close(); private: - basic_filebuf sb; // \expos + basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} @@ -12344,7 +12365,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} @@ -12358,9 +12379,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}% @@ -12377,9 +12398,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 @@ -12424,7 +12445,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} @@ -12441,7 +12462,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}% @@ -12467,7 +12488,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(sb))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_fstream}% @@ -12561,6 +12582,7 @@ #include // see \ref{ostream.syn} namespace std { + // \ref{syncstream.syncbuf}, class template \tcode{basic_syncbuf} template, class Allocator = allocator> class basic_syncbuf; @@ -12572,6 +12594,7 @@ using syncbuf = basic_syncbuf; using wsyncbuf = basic_syncbuf; + // \ref{syncstream.osyncstream}, class template \tcode{basic_osyncstream} template, class Allocator = allocator> class basic_osyncstream; @@ -12627,8 +12650,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} @@ -12638,7 +12661,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 @@ -12655,7 +12678,7 @@ \begin{itemdescr} \pnum \effects -Sets \tcode{wrapped} to \tcode{obuf}. +Sets \exposid{wrapped} to \tcode{obuf}. \pnum \ensures @@ -12789,10 +12812,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. @@ -12815,15 +12838,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}% @@ -12834,7 +12857,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wrapped}. +\exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_allocator}{basic_syncbuf}% @@ -12856,7 +12879,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} @@ -12870,9 +12893,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} @@ -12934,10 +12957,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} @@ -12979,8 +13002,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} @@ -13003,8 +13026,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 @@ -13025,7 +13048,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)}. @@ -13070,7 +13093,7 @@ \begin{itemdescr} \pnum \returns -\tcode{sb.get_wrapped()}. +\tcode{\exposid{sb}.get_wrapped()}. \pnum \begin{example} @@ -13595,7 +13618,8 @@ a pathname to a particular file in a file hierarchy. There may be multiple pathnames that resolve to the same file. \begin{example} -POSIX specifies the mechanism in section 4.12, Pathname resolution. +For POSIX-based operating systems, +this mechanism is specified in POSIX, section 4.12, Pathname resolution. \end{example} \begin{codeblock} @@ -13717,7 +13741,7 @@ path extension() const; // \ref{fs.path.query}, query - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; bool has_root_path() const; @@ -14064,14 +14088,14 @@ \item \tcode{basic_string_view}. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source.begin()}{source.end()}. -\item A type meeting the \oldconcept{InputIterator} requirements that iterates over a NTCTS\@. +\item A type meeting the \oldconcept{InputIterator} requirements that iterates over an NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to \tcode{iterator_traits::value_type()}. \item A character array that after array-to-pointer decay results in a - pointer to the start of a NTCTS\@. The value type shall be an encoded character type. A + pointer to the start of an NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to @@ -14963,7 +14987,7 @@ \indexlibrarymember{empty}{path}% \begin{itemdecl} -[[nodiscard]] bool empty() const noexcept; +bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -15686,10 +15710,10 @@ \lhdr{Constant} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{file_type}} & The type of the file has not been determined or an error occurred while trying to determine the type. \\ \rowsep -\tcode{not_found} & +\tcode{\libmember{not_found}{file_type}} & Pseudo-type indicating the file was not found. \begin{tailnote} The file @@ -15697,13 +15721,13 @@ type of a file. \end{tailnote} \\ \rowsep -\tcode{regular} & Regular file \\ \rowsep -\tcode{directory} & Directory file \\ \rowsep -\tcode{symlink} & Symbolic link file \\ \rowsep -\tcode{block} & Block special file \\ \rowsep -\tcode{character} & Character special file \\ \rowsep -\tcode{fifo} & FIFO or pipe file \\ \rowsep -\tcode{socket} & Socket file \\ \rowsep +\tcode{\libmember{regular}{file_type}} & Regular file \\ \rowsep +\tcode{\libmember{directory}{file_type}} & Directory file \\ \rowsep +\tcode{\libmember{symlink}{file_type}} & Symbolic link file \\ \rowsep +\tcode{\libmember{block}{file_type}} & Block special file \\ \rowsep +\tcode{\libmember{character}{file_type}} & Character special file \\ \rowsep +\tcode{\libmember{fifo}{file_type}} & FIFO or pipe file \\ \rowsep +\tcode{\libmember{socket}{file_type}} & Socket file \\ \rowsep \tcode{\textit{\impldef{additional \tcode{file_type} enumerators for file systems supporting additional types of file}}} & Implementations that support file systems having file types @@ -15713,7 +15737,7 @@ for file systems supporting additional types of file} \tcode{file_type} constants to separately identify each of those additional file types \\ \rowsep -\tcode{unknown} & +\tcode{\libmember{unknown}{file_type}} & The file exists but the type cannot be determined \\ \end{floattable} @@ -15735,42 +15759,42 @@ \topline \ohdrx{2}{Option group controlling \tcode{copy_file} function effects for existing target files} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{copy_options}} & (Default) Error; file already exists. \\ \rowsep -\tcode{skip_existing} & +\tcode{\libmember{skip_existing}{copy_options}} & Do not overwrite existing file, do not report an error. \\ \rowsep -\tcode{overwrite_existing} & +\tcode{\libmember{overwrite_existing}{copy_options}} & Overwrite the existing file. \\ \rowsep -\tcode{update_existing} & +\tcode{\libmember{update_existing}{copy_options}} & Overwrite the existing file if it is older than the replacement file. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for subdirectories} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{copy_options}} & (Default) Do not copy subdirectories. \\ \rowsep -\tcode{recursive} & +\tcode{\libmember{recursive}{copy_options}} & Recursively copy subdirectories and their contents. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for symbolic links} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{copy_options}} & (Default) Follow symbolic links. \\ \rowsep -\tcode{copy_symlinks} & +\tcode{\libmember{copy_symlinks}{copy_options}} & Copy symbolic links as symbolic links rather than copying the files that they point to. \\ \rowsep -\tcode{skip_symlinks} & +\tcode{\libmember{skip_symlinks}{copy_options}} & Ignore symbolic links. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for choosing the form of copying} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{copy_options}} & (Default) Copy content. \\ \rowsep -\tcode{directories_only} & +\tcode{\libmember{directories_only}{copy_options}} & Copy directory structure only, do not copy non-directory files. \\ \rowsep -\tcode{create_symlinks} & +\tcode{\libmember{create_symlinks}{copy_options}} & Make symbolic links instead of copies of files. The source path shall be an absolute path unless the destination path is in the current directory. \\ \rowsep -\tcode{create_hard_links} & +\tcode{\libmember{create_hard_links}{copy_options}} & Make hard links instead of copies of files. \\ \end{floattable} @@ -15789,46 +15813,46 @@ \lhdr{Name} & \chdr{Value} & \chdr{POSIX} & \rhdr{Definition or notes} \\ & \chdr{(octal)} & \chdr{macro} & \\ \capsep -\tcode{none} & \tcode{0} & & +\tcode{\libmember{none}{perms}} & \tcode{0} & & There are no permissions set for the file. \\ \rowsep -\tcode{owner_read} & \tcode{0400} & \tcode{S_IRUSR} & +\tcode{\libmember{owner_read}{perms}} & \tcode{0400} & \tcode{S_IRUSR} & Read permission, owner \\ \rowsep -\tcode{owner_write} & \tcode{0200} & \tcode{S_IWUSR} & +\tcode{\libmember{owner_write}{perms}} & \tcode{0200} & \tcode{S_IWUSR} & Write permission, owner \\ \rowsep -\tcode{owner_exec} & \tcode{0100} & \tcode{S_IXUSR} & +\tcode{\libmember{owner_exec}{perms}} & \tcode{0100} & \tcode{S_IXUSR} & Execute/search permission, owner \\ \rowsep -\tcode{owner_all} & \tcode{0700} & \tcode{S_IRWXU} & +\tcode{\libmember{owner_all}{perms}} & \tcode{0700} & \tcode{S_IRWXU} & Read, write, execute/search by owner;\br \tcode{owner_read | owner_write | owner_exec} \\ \rowsep -\tcode{group_read} & \tcode{040} & \tcode{S_IRGRP} & +\tcode{\libmember{group_read}{perms}} & \tcode{040} & \tcode{S_IRGRP} & Read permission, group \\ \rowsep -\tcode{group_write} & \tcode{020} & \tcode{S_IWGRP} & +\tcode{\libmember{group_write}{perms}} & \tcode{020} & \tcode{S_IWGRP} & Write permission, group \\ \rowsep -\tcode{group_exec} & \tcode{010} & \tcode{S_IXGRP} & +\tcode{\libmember{group_exec}{perms}} & \tcode{010} & \tcode{S_IXGRP} & Execute/search permission, group \\ \rowsep -\tcode{group_all} & \tcode{070} & \tcode{S_IRWXG} & +\tcode{\libmember{group_all}{perms}} & \tcode{070} & \tcode{S_IRWXG} & Read, write, execute/search by group;\br \tcode{group_read | group_write | group_exec} \\ \rowsep -\tcode{others_read} & \tcode{04} & \tcode{S_IROTH} & +\tcode{\libmember{others_read}{perms}} & \tcode{04} & \tcode{S_IROTH} & Read permission, others \\ \rowsep -\tcode{others_write} & \tcode{02} & \tcode{S_IWOTH} & +\tcode{\libmember{others_write}{perms}} & \tcode{02} & \tcode{S_IWOTH} & Write permission, others \\ \rowsep -\tcode{others_exec} & \tcode{01} & \tcode{S_IXOTH} & +\tcode{\libmember{others_exec}{perms}} & \tcode{01} & \tcode{S_IXOTH} & Execute/search permission, others \\ \rowsep -\tcode{others_all} & \tcode{07} & \tcode{S_IRWXO} & +\tcode{\libmember{others_all}{perms}} & \tcode{07} & \tcode{S_IRWXO} & Read, write, execute/search by others;\br \tcode{others_read | others_write | others_exec} \\ \rowsep -\tcode{all} & \tcode{0777} & & +\tcode{\libmember{all}{perms}} & \tcode{0777} & & \tcode{owner_all | group_all | others_all} \\ \rowsep -\tcode{set_uid} & \tcode{04000} & \tcode{S_ISUID} & +\tcode{\libmember{set_uid}{perms}} & \tcode{04000} & \tcode{S_ISUID} & Set-user-ID on execution \\ \rowsep -\tcode{set_gid} & \tcode{02000} & \tcode{S_ISGID} & +\tcode{\libmember{set_gid}{perms}} & \tcode{02000} & \tcode{S_ISGID} & Set-group-ID on execution \\ \rowsep -\tcode{sticky_bit} & \tcode{01000} & \tcode{S_ISVTX} & +\tcode{\libmember{sticky_bit}{perms}} & \tcode{01000} & \tcode{S_ISVTX} & Operating system dependent. \\ \rowsep -\tcode{mask} & \tcode{07777} & & +\tcode{\libmember{mask}{perms}} & \tcode{07777} & & \tcode{all | set_uid | set_gid | sticky_bit} \\ \rowsep -\tcode{unknown} & \tcode{0xFFFF} & & +\tcode{\libmember{unknown}{perms}} & \tcode{0xFFFF} & & The permissions are not known, such as when a \tcode{file_status} object is created without specifying the permissions \\ \end{floattable} @@ -15850,15 +15874,15 @@ \topline \lhdr{Name} & \rhdr{Meaning} \\ \capsep -\tcode{replace} & +\tcode{\libmember{replace}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with \tcode{perm} \\ \rowsep -\tcode{add} & +\tcode{\libmember{add}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with the bitwise \logop{or} of \tcode{perm} and the file's current permission bits. \\ \rowsep -\tcode{remove} & +\tcode{\libmember{remove}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with the bitwise \logop{and} of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep -\tcode{nofollow} & +\tcode{\libmember{nofollow}{perm_options}} & \tcode{permissions} shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. \\ \end{floattable} @@ -15881,11 +15905,11 @@ \lhdr{Name} & \rhdr{Meaning} \\ \capsep -\tcode{none} & +\tcode{\libmember{none}{directory_options}} & (Default) Skip directory symlinks, permission denied is an error. \\ \rowsep -\tcode{follow_directory_symlink} & +\tcode{\libmember{follow_directory_symlink}{directory_options}} & Follow rather than skip directory symlinks. \\ \rowsep -\tcode{skip_permission_denied} & +\tcode{\libmember{skip_permission_denied}{directory_options}} & Skip directories that would otherwise result in permission denied. \\ \end{floattable} @@ -16060,8 +16084,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} @@ -16080,13 +16103,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 @@ -16155,7 +16175,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. @@ -16173,7 +16193,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. @@ -16224,7 +16244,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject}. +\exposid{path-object}. \end{itemdescr} \indexlibrarymember{exists}{directory_entry}% @@ -16464,7 +16484,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pathobject == rhs.pathobject}. +\tcode{\exposid{path-object} == rhs.\exposid{path-object}}. \end{itemdescr} \indexlibrarymember{operator<=>}{directory_entry}% @@ -16475,7 +16495,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} @@ -16585,8 +16605,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 @@ -17076,7 +17094,7 @@ \pnum \begin{note} -\tcode{disable_recursion_pending}\tcode{()} is used to prevent +\tcode{disable_recursion_pending()} is used to prevent unwanted recursion into a directory. \end{note} \end{itemdescr} @@ -17271,7 +17289,7 @@ \impldef{effect of \tcode{filesystem::copy}}. \item -Otherwise, an error is reported as specified in~\ref{fs.err.report} if: +Otherwise, an error is reported as specified in~\ref{fs.err.report} if \begin{itemize} \item \tcode{exists(f)} is \tcode{false}, or \item \tcode{equivalent(from, to)} is \tcode{true}, or @@ -17354,16 +17372,16 @@ \pnum \begin{example} Given this directory structure: -\begin{codeblock} +\begin{outputblock} /dir1 file1 file2 dir2 file3 -\end{codeblock} +\end{outputblock} Calling \tcode{copy("/dir1", "/dir3")} would result in: -\begin{codeblock} +\begin{outputblock} /dir1 file1 file2 @@ -17372,10 +17390,10 @@ /dir3 file1 file2 -\end{codeblock} +\end{outputblock} Alternatively, calling \tcode{copy("/dir1", "/dir3", copy_options::recursive)} would result in: -\begin{codeblock} +\begin{outputblock} /dir1 file1 file2 @@ -17386,7 +17404,7 @@ file2 dir2 file3 -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -17429,7 +17447,7 @@ As follows: \begin{itemize} \item -Report an error as specified in~\ref{fs.err.report} if: +Report an error as specified in~\ref{fs.err.report} if \begin{itemize} \item \tcode{is_regular_file(from)} is \tcode{false}, or \item \tcode{exists(to)} is \tcode{true} and \tcode{is_regular_file(to)} is \tcode{false}, or @@ -17444,7 +17462,7 @@ \item Otherwise, copy the contents and attributes of the file \tcode{from} - resolves to, to the file \tcode{to} resolves to, if: + resolves to, to the file \tcode{to} resolves to, if \begin{itemize} \item \tcode{exists(to)} is \tcode{false}, or \item \tcode{(options \& copy_options::overwrite_existing) != copy_options::none}, or @@ -17506,7 +17524,7 @@ \begin{itemdescr} \pnum \effects -Calls \tcode{create_directory()} for each element of \tcode{p} +Calls \tcode{create_directory} for each element of \tcode{p} that does not exist. \pnum @@ -17599,7 +17617,7 @@ \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{symlink()}. +Establishes the postcondition, as if by POSIX \tcode{symlink}. \pnum \ensures @@ -17614,7 +17632,7 @@ \begin{note} Some operating systems require symlink creation to identify that the link is to a directory. -Thus, \tcode{create_symlink()} (instead of \tcode{create_directory_symlink()}) +Thus, \tcode{create_symlink} (instead of \tcode{create_directory_symlink}) cannot be used reliably to create directory symlinks. \end{note} @@ -17640,7 +17658,7 @@ \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{link()}. +Establishes the postcondition, as if by POSIX \tcode{link}. \pnum \ensures @@ -17675,7 +17693,7 @@ \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{symlink()}. +Establishes the postcondition, as if by POSIX \tcode{symlink}. \pnum \ensures @@ -17708,7 +17726,7 @@ \returns The absolute path of the current working directory, whose pathname in the native format is - obtained as if by POSIX \tcode{getcwd()}. + obtained as if by POSIX \tcode{getcwd}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. @@ -17722,12 +17740,6 @@ with the process, that is used as the starting location in pathname resolution for relative paths. -\pnum -\begin{note} -The \tcode{current_path()} name was chosen to emphasize that the returned value is a - path, not just a single directory name. -\end{note} - \pnum \begin{note} The current path as returned by many operating systems is a dangerous @@ -17745,7 +17757,7 @@ \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{chdir()}. +Establishes the postcondition, as if by POSIX \tcode{chdir}. \pnum \ensures @@ -17778,7 +17790,7 @@ \begin{note} On POSIX platforms, this is determined as if by the values of the POSIX \tcode{stat} class, - obtained as if by \tcode{stat()} for the two paths, having equal \tcode{st_dev} values + obtained as if by \tcode{stat} for the two paths, having equal \tcode{st_dev} values and equal \tcode{st_ino} values. \end{note} @@ -17856,7 +17868,7 @@ \item If \tcode{is_regular_file(p)}, the size in bytes of the file \tcode{p} resolves to, determined as if by the value of the POSIX \tcode{stat} - class member \tcode{st_size} obtained as if by POSIX \tcode{stat()}. + class member \tcode{st_size} obtained as if by POSIX \tcode{stat}. \item Otherwise, the result is \impldef{result of \tcode{filesystem::file_size}}. \end{itemize} @@ -18218,7 +18230,7 @@ \returns The time of last data modification of \tcode{p}, determined as if by the value of the POSIX \tcode{stat} class member \tcode{st_mtime} - obtained as if by POSIX \tcode{stat()}. + obtained as if by POSIX \tcode{stat}. The signature with argument \tcode{ec} returns \tcode{file_time_type::min()} if an error occurs. @@ -18238,7 +18250,7 @@ \pnum \effects Sets the time of last data modification of the file - resolved to by \tcode{p} to \tcode{new_time}, as if by POSIX \tcode{futimens()}. + resolved to by \tcode{p} to \tcode{new_time}, as if by POSIX \tcode{futimens}. \pnum \throws @@ -18272,7 +18284,7 @@ to the file \tcode{p} resolves to, or to file \tcode{p} itself if \tcode{p} is a symbolic link and \tcode{perm_options::nofollow} is set in \tcode{opts}. -The action is applied as if by POSIX \tcode{fchmodat()}. +The action is applied as if by POSIX \tcode{fchmodat}. \pnum \begin{note} @@ -18409,7 +18421,7 @@ \pnum \effects If \tcode{exists(symlink_status(p, ec))}, the file \tcode{p} is - removed as if by POSIX \tcode{remove()}. + removed as if by POSIX \tcode{remove}. \begin{note} A symbolic link is itself removed, rather than the file it resolves to. @@ -18421,9 +18433,10 @@ \pnum \returns -\tcode{false} if \tcode{p} did not exist, - otherwise \tcode{true}. The signature with argument \tcode{ec} - returns \tcode{false} if an error occurs. +\tcode{true} if a file \tcode{p} has been removed and \tcode{false} otherwise. +\begin{note} +Absence of a file \tcode{p} is not an error. +\end{note} \pnum \throws @@ -18443,7 +18456,7 @@ \pnum \effects Recursively deletes the contents of \tcode{p} if it exists, - then deletes file \tcode{p} itself, as if by POSIX \tcode{remove()}. + then deletes file \tcode{p} itself, as if by POSIX \tcode{remove}. \begin{note} A symbolic link is itself removed, rather than the file it resolves to. @@ -18477,7 +18490,7 @@ \pnum \effects Renames \tcode{old_p} to \tcode{new_p}, as if by - POSIX \tcode{rename()}. + POSIX \tcode{rename}. \begin{note} \begin{itemize} @@ -18513,7 +18526,7 @@ \pnum \effects Causes the size that would be returned by \tcode{file_size(p)} to be -equal to \tcode{new_size}, as if by POSIX \tcode{truncate()}. +equal to \tcode{new_size}, as if by POSIX \tcode{truncate}. \pnum \throws @@ -18568,7 +18581,7 @@ \begin{itemdescr} \pnum \effects -As if: +As if by: \begin{codeblock} error_code ec; file_status result = status(p, ec); @@ -18600,14 +18613,14 @@ \pnum \effects If possible, determines the attributes - of the file \tcode{p} resolves to, as if by using POSIX \tcode{stat()} + of the file \tcode{p} resolves to, as if by using POSIX \tcode{stat} to obtain a POSIX \tcode{struct stat}. If, during attribute determination, the underlying file system API reports an error, sets \tcode{ec} to indicate the specific error reported. Otherwise, \tcode{ec.clear()}. \begin{note} This allows users to inspect the specifics of underlying - API errors even when the value returned by \tcode{status()} is not + API errors even when the value returned by \tcode{status} is not \tcode{file_status(file_type::none)}. \end{note} @@ -18701,9 +18714,9 @@ \begin{itemdescr} \pnum \effects -Same as \tcode{status()}, above, +Same as \tcode{status}, above, except that the attributes - of \tcode{p} are determined as if by using POSIX \tcode{lstat()} + of \tcode{p} are determined as if by using POSIX \tcode{lstat} to obtain a POSIX \tcode{struct stat}. \pnum @@ -18713,7 +18726,7 @@ \pnum \returns -Same as \tcode{status()}, above, except +Same as \tcode{status}, above, except that if the attributes indicate a symbolic link, as if by POSIX \tcode{S_ISLNK}, returns \tcode{file_status(file_type::symlink, prms)}. The signature with argument \tcode{ec} returns @@ -18782,14 +18795,14 @@ Using \tcode{status(p)} or \tcode{status(p, ec)}, respectively, to determine existence, return a path composed by \tcode{operator/=} - from the result of calling \tcode{canonical()} + from the result of calling \tcode{canonical} with a path argument composed of the leading elements of \tcode{p} that exist, if any, followed by the elements of \tcode{p} that do not exist, if any. For the first form, - \tcode{canonical()} is called without an \tcode{error_code} argument. + \tcode{canonical} is called without an \tcode{error_code} argument. For the second form, - \tcode{canonical()} is called + \tcode{canonical} is called with \tcode{ec} as an \tcode{error_code} argument, and \tcode{path()} is returned at the first error occurrence, if any. @@ -18815,22 +18828,6 @@ \indexlibraryglobal{size_t}% \indexlibraryglobal{FILE}% \indexlibraryglobal{fpos_t}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{_IOFBF}% -\indexlibraryglobal{_IOLBF}% -\indexlibraryglobal{_IONBF}% -\indexlibraryglobal{BUFSIZ}% -\indexlibraryglobal{EOF}% -\indexlibraryglobal{FOPEN_MAX}% -\indexlibraryglobal{FILENAME_MAX}% -\indexlibraryglobal{L_tmpnam}% -\indexlibraryglobal{SEEK_CUR}% -\indexlibraryglobal{SEEK_END}% -\indexlibraryglobal{SEEK_SET}% -\indexlibraryglobal{TMP_MAX}% -\indexlibraryglobal{stderr}% -\indexlibraryglobal{stdin}% -\indexlibraryglobal{stdout}% \indexlibraryglobal{remove}% \indexlibraryglobal{rename}% \indexlibraryglobal{tmpfile}% @@ -18883,22 +18880,22 @@ using fpos_t = @\seebelow@; } -#define NULL @\textit{see \ref{support.types.nullptr}}@ -#define _IOFBF @\seebelow@ -#define _IOLBF @\seebelow@ -#define _IONBF @\seebelow@ -#define BUFSIZ @\seebelow@ -#define EOF @\seebelow@ -#define FOPEN_MAX @\seebelow@ -#define FILENAME_MAX @\seebelow@ -#define L_tmpnam @\seebelow@ -#define SEEK_CUR @\seebelow@ -#define SEEK_END @\seebelow@ -#define SEEK_SET @\seebelow@ -#define TMP_MAX @\seebelow@ -#define stderr @\seebelow@ -#define stdin @\seebelow@ -#define stdout @\seebelow@ +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ +#define @\libmacro{_IOFBF}@ @\seebelow@ +#define @\libmacro{_IOLBF}@ @\seebelow@ +#define @\libmacro{_IONBF}@ @\seebelow@ +#define @\libmacro{BUFSIZ}@ @\seebelow@ +#define @\libmacro{EOF}@ @\seebelow@ +#define @\libmacro{FOPEN_MAX}@ @\seebelow@ +#define @\libmacro{FILENAME_MAX}@ @\seebelow@ +#define @\libmacro{L_tmpnam}@ @\seebelow@ +#define @\libmacro{SEEK_CUR}@ @\seebelow@ +#define @\libmacro{SEEK_END}@ @\seebelow@ +#define @\libmacro{SEEK_SET}@ @\seebelow@ +#define @\libmacro{TMP_MAX}@ @\seebelow@ +#define @\libmacro{stderr}@ @\seebelow@ +#define @\libmacro{stdin}@ @\seebelow@ +#define @\libmacro{stdout}@ @\seebelow@ namespace std { int remove(const char* filename); @@ -18953,6 +18950,13 @@ The contents and meaning of the header \libheader{cstdio} are the same as the C standard library header \libheader{stdio.h}. +\pnum +The return from each function call +that delivers data +to the host environment +to be written to a file (\xrefc{7.21.3}) +is an observable checkpoint\iref{intro.abstract}. + \pnum Calls to the function \tcode{tmpnam} with an argument that is a null pointer value may introduce a data race\iref{res.on.data.races} with other calls to \tcode{tmpnam} with @@ -19005,28 +19009,6 @@ \indexlibraryglobal{SCNoFASTN}% \indexlibraryglobal{SCNuFASTN}% \indexlibraryglobal{SCNxFASTN}% -\indexlibraryglobal{PRIdMAX}% -\indexlibraryglobal{PRIiMAX}% -\indexlibraryglobal{PRIoMAX}% -\indexlibraryglobal{PRIuMAX}% -\indexlibraryglobal{PRIxMAX}% -\indexlibraryglobal{PRIXMAX}% -\indexlibraryglobal{SCNdMAX}% -\indexlibraryglobal{SCNiMAX}% -\indexlibraryglobal{SCNoMAX}% -\indexlibraryglobal{SCNuMAX}% -\indexlibraryglobal{SCNxMAX}% -\indexlibraryglobal{PRIdPTR}% -\indexlibraryglobal{PRIiPTR}% -\indexlibraryglobal{PRIoPTR}% -\indexlibraryglobal{PRIuPTR}% -\indexlibraryglobal{PRIxPTR}% -\indexlibraryglobal{PRIXPTR}% -\indexlibraryglobal{SCNdPTR}% -\indexlibraryglobal{SCNiPTR}% -\indexlibraryglobal{SCNoPTR}% -\indexlibraryglobal{SCNuPTR}% -\indexlibraryglobal{SCNxPTR}% \begin{codeblock} #include // see \ref{cstdint.syn} @@ -19077,28 +19059,28 @@ #define SCNoFAST@\placeholdernc{N}@ @\seebelow@ #define SCNuFAST@\placeholdernc{N}@ @\seebelow@ #define SCNxFAST@\placeholdernc{N}@ @\seebelow@ -#define PRIdMAX @\seebelow@ -#define PRIiMAX @\seebelow@ -#define PRIoMAX @\seebelow@ -#define PRIuMAX @\seebelow@ -#define PRIxMAX @\seebelow@ -#define PRIXMAX @\seebelow@ -#define SCNdMAX @\seebelow@ -#define SCNiMAX @\seebelow@ -#define SCNoMAX @\seebelow@ -#define SCNuMAX @\seebelow@ -#define SCNxMAX @\seebelow@ -#define PRIdPTR @\seebelow@ -#define PRIiPTR @\seebelow@ -#define PRIoPTR @\seebelow@ -#define PRIuPTR @\seebelow@ -#define PRIxPTR @\seebelow@ -#define PRIXPTR @\seebelow@ -#define SCNdPTR @\seebelow@ -#define SCNiPTR @\seebelow@ -#define SCNoPTR @\seebelow@ -#define SCNuPTR @\seebelow@ -#define SCNxPTR @\seebelow@ +#define @\libmacro{PRIdMAX}@ @\seebelow@ +#define @\libmacro{PRIiMAX}@ @\seebelow@ +#define @\libmacro{PRIoMAX}@ @\seebelow@ +#define @\libmacro{PRIuMAX}@ @\seebelow@ +#define @\libmacro{PRIxMAX}@ @\seebelow@ +#define @\libmacro{PRIXMAX}@ @\seebelow@ +#define @\libmacro{SCNdMAX}@ @\seebelow@ +#define @\libmacro{SCNiMAX}@ @\seebelow@ +#define @\libmacro{SCNoMAX}@ @\seebelow@ +#define @\libmacro{SCNuMAX}@ @\seebelow@ +#define @\libmacro{SCNxMAX}@ @\seebelow@ +#define @\libmacro{PRIdPTR}@ @\seebelow@ +#define @\libmacro{PRIiPTR}@ @\seebelow@ +#define @\libmacro{PRIoPTR}@ @\seebelow@ +#define @\libmacro{PRIuPTR}@ @\seebelow@ +#define @\libmacro{PRIxPTR}@ @\seebelow@ +#define @\libmacro{PRIXPTR}@ @\seebelow@ +#define @\libmacro{SCNdPTR}@ @\seebelow@ +#define @\libmacro{SCNiPTR}@ @\seebelow@ +#define @\libmacro{SCNoPTR}@ @\seebelow@ +#define @\libmacro{SCNuPTR}@ @\seebelow@ +#define @\libmacro{SCNxPTR}@ @\seebelow@ \end{codeblock} \pnum diff --git a/source/iterators.tex b/source/iterators.tex index c59e2264c3..d148a6489a 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -84,6 +84,7 @@ template concept indirectly_readable = @\seebelow@; // freestanding + // \ref{indirectcallable.traits}, indirect callable traits template<@\libconcept{indirectly_readable}@ T> using @\exposidnc{indirect-value-t}@ = @\seebelow@; // \expos @@ -168,11 +169,7 @@ // \ref{projected}, projected template<@\libconcept{indirectly_readable}@ I, @\libconcept{indirectly_regular_unary_invocable}@ Proj> - struct projected; // freestanding - - template<@\libconcept{weakly_incrementable}@ I, class Proj> - struct incrementable_traits>; // freestanding - + using projected = @\seebelow@; // freestanding template<@\libconcept{indirectly_readable}@ I, @\libconcept{indirectly_regular_unary_invocable}@ Proj> using projected_value_t = // freestanding @@ -207,7 +204,7 @@ // \ref{alg.req.mergeable}, concept \libconcept{mergeable} template + class R = ranges::less, class P1 = identity, class P2 = identity> concept mergeable = @\seebelow@; // freestanding // \ref{alg.req.sortable}, concept \libconcept{sortable} @@ -324,7 +321,7 @@ constexpr reverse_iterator make_reverse_iterator(Iterator i); // freestanding template - requires (!@\libconcept{sized_sentinel_for}@) + requires (!@\libconcept{sized_sentinel_for}@) constexpr bool @\libspec{disable_sized_sentinel_for}{reverse_iterator}@, // freestanding reverse_iterator> = true; @@ -414,7 +411,7 @@ constexpr move_iterator make_move_iterator(Iterator i); // freestanding template - requires (!@\libconcept{sized_sentinel_for}@) + requires (!@\libconcept{sized_sentinel_for}@) constexpr bool @\libspec{disable_sized_sentinel_for}{move_iterator}@, // freestanding move_iterator> = true; @@ -455,7 +452,7 @@ const istream_iterator& y); template> - class ostream_iterator; + class ostream_iterator; template> class istreambuf_iterator; @@ -503,11 +500,11 @@ template constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // freestanding - template [[nodiscard]] constexpr auto + template constexpr auto empty(const C& c) -> decltype(c.empty()); // freestanding - template [[nodiscard]] constexpr bool + template constexpr bool empty(const T (&array)[N]) noexcept; // freestanding - template [[nodiscard]] constexpr bool + template constexpr bool empty(initializer_list il) noexcept; // freestanding template constexpr auto data(C& c) -> decltype(c.data()); // freestanding @@ -519,7 +516,7 @@ \rSec1[iterator.requirements]{Iterator requirements} -\rSec2[iterator.requirements.general]{In general} +\rSec2[iterator.requirements.general]{General} \pnum \indextext{requirements!iterator}% @@ -538,7 +535,7 @@ \defn{value type} of the iterator. An output iterator \tcode{i} has a non-empty set of types that are -\libconcept{indirectly_writable} to the iterator; +\defn{writable} to the iterator; for each such type \tcode{T}, the expression \tcode{*i = o} is valid where \tcode{o} is a value of type \tcode{T}. For every iterator type @@ -692,6 +689,24 @@ The result of the application of library functions to invalid ranges is undefined. +\pnum +For an iterator \tcode{i} of a type that +models \libconcept{contiguous_iterator}\iref{iterator.concept.contiguous}, +library functions are permitted +to replace \range{i}{s} with +\range{to_address(i)}{to_address(i + ranges::distance(i, s))}, and +to replace \countedrange{i}{n} with \range{to_address(i)}{to_address(i + n)}. +\begin{note} +This means a program cannot rely on any side effects of +dereferencing a contiguous iterator \tcode{i}, +because library functions might operate on +pointers obtained by \tcode{to_address(i)} +instead of operating on \tcode{i}. +Similarly, a program cannot rely on any side effects of +individual increments on a contiguous iterator \tcode{i}, +because library functions might advance \tcode{i} only once. +\end{note} + \pnum All the categories of iterators require only those functions that are realizable for a given category in constant time (amortized). @@ -1338,7 +1353,7 @@ \pnum Let \tcode{E} be an expression such that \tcode{decltype((E))} is \tcode{T}, and let \tcode{o} be a dereferenceable object of type \tcode{Out}. -\tcode{Out} and \tcode{T} model \tcode{\libconcept{indirectly_writable}} only if +\tcode{Out} and \tcode{T} model \tcode{\libconcept{indirectly_writable}} only if: \begin{itemize} \item If \tcode{Out} and \tcode{T} model \tcode{\libconcept{indirectly_readable} \&\& \libconcept{same_as}, decay_t>}, @@ -1544,7 +1559,7 @@ \pnum Let \tcode{i} be an object of type \tcode{I}. When \tcode{i} is in the domain of both pre- and post-increment, \tcode{i} is said to be \defn{incrementable}. -\tcode{I} models \tcode{\libconcept{weakly_incrementable}} only if +\tcode{I} models \tcode{\libconcept{weakly_incrementable}} only if: \begin{itemize} \item The expressions \tcode{++i} and \tcode{i++} have the same domain. \item If \tcode{i} is incrementable, then both \tcode{++i} @@ -1591,7 +1606,7 @@ \pnum Let \tcode{a} and \tcode{b} be incrementable objects of type \tcode{I}. -\tcode{I} models \libconcept{incrementable} only if +\tcode{I} models \libconcept{incrementable} only if: \begin{itemize} \item If \tcode{bool(a == b)} then \tcode{bool(a++ == b)}. \item If \tcode{bool(a == b)} then \tcode{bool(((void)a++, a) == ++b)}. @@ -1654,7 +1669,7 @@ \pnum Let \tcode{s} and \tcode{i} be values of type \tcode{S} and \tcode{I} such that \range{i}{s} denotes a range. Types -\tcode{S} and \tcode{I} model \tcode{\libconcept{sentinel_for}} only if +\tcode{S} and \tcode{I} model \tcode{\libconcept{sentinel_for}} only if: \begin{itemize} \item \tcode{i == s} is well-defined. @@ -1699,7 +1714,7 @@ a sentinel of type \tcode{S} such that \range{i}{s} denotes a range. Let $N$ be the smallest number of applications of \tcode{++i} necessary to make \tcode{bool(i == s)} be \tcode{true}. -\tcode{S} and \tcode{I} model \tcode{\libconcept{sized_sentinel_for}} only if +\tcode{S} and \tcode{I} model \tcode{\libconcept{sized_sentinel_for}} only if: \begin{itemize} \item If $N$ is representable by \tcode{iter_difference_t}, then \tcode{s - i} is well-defined and equals $N$. @@ -1829,7 +1844,7 @@ \pnum Two dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{X} -offer the \defn{multi-pass guarantee} if: +offer the \defn{multi-pass guarantee} if \begin{itemize} \item \tcode{a == b} implies \tcode{++a == ++b} and \item the expression @@ -1918,7 +1933,7 @@ after \tcode{n} applications of \tcode{++a}, let \tcode{D} be \tcode{iter_difference_t}, and let \tcode{n} denote a value of type \tcode{D}. -\tcode{I} models \libconcept{random_access_iterator} only if +\tcode{I} models \libconcept{random_access_iterator} only if: \begin{itemize} \item \tcode{(a += n)} is equal to \tcode{b}. \item \tcode{addressof(a += n)} is equal to \tcode{addressof(a)}. @@ -1968,6 +1983,7 @@ \item \tcode{to_address(a) == addressof(*a)}, \item \tcode{to_address(b) == to_address(a) + D(b - a)}, \item \tcode{to_address(c) == to_address(a) + D(c - a)}, +\item \tcode{to_address(I\{\})} is well-defined, \item \tcode{ranges::iter_move(a)} has the same type, value category, and effects as \tcode{std::move(*a)}, and \item if \tcode{ranges::iter_swap(a, b)} is well-formed, @@ -2021,7 +2037,7 @@ bidirectional.iterators,random.access.iterators}. \pnum -A type \tcode{X} meets the \defnoldconcept{Iterator} requirements if: +A type \tcode{X} meets the \defnoldconcept{Iterator} requirements if \begin{itemize} \item \tcode{X} meets the \oldconcept{CopyConstructible}, \oldconcept{CopyAssignable}, \oldconcept{Swappable}, and \oldconcept{Destructible} requirements\iref{utility.arg.requirements,swappable.requirements}, and @@ -2246,7 +2262,7 @@ \pnum Two dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{X} offer the -\defn{multi-pass guarantee} if: +\defn{multi-pass guarantee} if \begin{itemize} \item \tcode{a == b} implies \tcode{++a == ++b} and \item \tcode{X} is a pointer type or the expression @@ -2449,7 +2465,6 @@ @\libconcept{copy_constructible}@ && @\libconcept{invocable}@> && @\libconcept{invocable}@> && - @\libconcept{invocable}@> && @\libconcept{common_reference_with}@< invoke_result_t>, invoke_result_t>>; @@ -2460,7 +2475,6 @@ @\libconcept{copy_constructible}@ && @\libconcept{regular_invocable}@> && @\libconcept{regular_invocable}@> && - @\libconcept{regular_invocable}@> && @\libconcept{common_reference_with}@< invoke_result_t>, invoke_result_t>>; @@ -2470,8 +2484,7 @@ @\libconcept{indirectly_readable}@ && @\libconcept{copy_constructible}@ && @\libconcept{predicate}@> && - @\libconcept{predicate}@> && - @\libconcept{predicate}@>; + @\libconcept{predicate}@>; template concept @\deflibconcept{indirect_binary_predicate}@ = @@ -2480,8 +2493,7 @@ @\libconcept{predicate}@, @\exposidnc{indirect-value-t}@> && @\libconcept{predicate}@, iter_reference_t> && @\libconcept{predicate}@, @\exposidnc{indirect-value-t}@> && - @\libconcept{predicate}@, iter_reference_t> && - @\libconcept{predicate}@, iter_common_reference_t>; + @\libconcept{predicate}@, iter_reference_t>; template concept @\deflibconcept{indirect_equivalence_relation}@ = @@ -2490,8 +2502,7 @@ @\libconcept{equivalence_relation}@, @\exposidnc{indirect-value-t}@> && @\libconcept{equivalence_relation}@, iter_reference_t> && @\libconcept{equivalence_relation}@, @\exposidnc{indirect-value-t}@> && - @\libconcept{equivalence_relation}@, iter_reference_t> && - @\libconcept{equivalence_relation}@, iter_common_reference_t>; + @\libconcept{equivalence_relation}@, iter_reference_t>; template concept @\deflibconcept{indirect_strict_weak_order}@ = @@ -2500,8 +2511,7 @@ @\libconcept{strict_weak_order}@, @\exposidnc{indirect-value-t}@> && @\libconcept{strict_weak_order}@, iter_reference_t> && @\libconcept{strict_weak_order}@, @\exposidnc{indirect-value-t}@> && - @\libconcept{strict_weak_order}@, iter_reference_t> && - @\libconcept{strict_weak_order}@, iter_common_reference_t>; + @\libconcept{strict_weak_order}@, iter_reference_t>; } \end{codeblock} @@ -2937,32 +2947,8 @@ \end{example} \pnum -The function templates defined in \ref{range.iter.ops} are not found by -argument-dependent name lookup\iref{basic.lookup.argdep}. When found by -unqualified\iref{basic.lookup.unqual} name lookup for the -\grammarterm{postfix-expression} in a function call\iref{expr.call}, they -inhibit argument-dependent name lookup. - -\begin{example} -\begin{codeblock} -void foo() { - using namespace std::ranges; - std::vector vec{1,2,3}; - distance(begin(vec), end(vec)); // \#1 -} -\end{codeblock} -The function call expression at \tcode{\#1} invokes \tcode{std::ranges::distance}, -not \tcode{std::distance}, despite that -(a) the iterator type returned from \tcode{begin(vec)} and \tcode{end(vec)} -may be associated with namespace \tcode{std} and -(b) \tcode{std::distance} is more specialized\iref{temp.func.order} than -\tcode{std::ranges::distance} since the former requires its first two parameters -to have the same type. -\end{example} - -\pnum -The number and order of deducible template parameters for the function templates defined -in \ref{range.iter.ops} is unspecified, except where explicitly stated otherwise. +The entities defined in \ref{range.iter.ops} are +algorithm function objects\iref{alg.func.obj}. \rSec3[range.iter.op.advance]{\tcode{ranges::advance}} @@ -3323,9 +3309,6 @@ \effects Value-initializes \tcode{current}. -Iterator operations applied to the resulting iterator have defined behavior -if and only if the corresponding operations are defined on a value-initialized iterator of type -\tcode{Iterator}. \end{itemdescr} \indexlibraryctor{reverse_iterator}% @@ -3441,7 +3424,7 @@ \begin{itemdescr} \pnum \returns -\tcode{current[-n-1]}. +\tcode{current[-n - 1]}. \end{itemdescr} \rSec3[reverse.iter.nav]{Navigation} @@ -3454,7 +3437,7 @@ \begin{itemdescr} \pnum \returns -\tcode{reverse_iterator(current-n)}. +\tcode{reverse_iterator(current - n)}. \end{itemdescr} \indexlibrarymember{operator-}{reverse_iterator}% @@ -3465,7 +3448,7 @@ \begin{itemdescr} \pnum \returns -\tcode{reverse_iterator(current+n)}. +\tcode{reverse_iterator(current + n)}. \end{itemdescr} \indexlibrarymember{operator++}{reverse_iterator}% @@ -3842,6 +3825,8 @@ \rSec3[back.insert.iterator]{Class template \tcode{back_insert_iterator}} +\rSec4[back.insert.iter.general]{General} + \indexlibraryglobal{back_insert_iterator}% \begin{codeblock} namespace std { @@ -3953,6 +3938,8 @@ \rSec3[front.insert.iterator]{Class template \tcode{front_insert_iterator}} +\rSec4[front.insert.iter.general]{General} + \indexlibraryglobal{front_insert_iterator}% \begin{codeblock} namespace std { @@ -4064,6 +4051,8 @@ \rSec3[insert.iterator]{Class template \tcode{insert_iterator}} +\rSec4[insert.iter.general]{General} + \indexlibraryglobal{insert_iterator}% \begin{codeblock} namespace std { @@ -4264,7 +4253,7 @@ template<@\libconcept{convertible_to}@ U> constexpr basic_const_iterator(basic_const_iterator current); template<@\exposconcept{different-from}@ T> - requires @\libconcept{convertible_to}@ + requires @\libconcept{convertible_to}@ constexpr basic_const_iterator(T&& current); constexpr const Iterator& base() const & noexcept; @@ -4272,8 +4261,8 @@ constexpr @\exposid{reference}@ operator*() const; constexpr const auto* operator->() const - requires is_lvalue_reference_v> && - @\libconcept{same_as}@>, value_type>; + requires is_lvalue_reference_v> && + @\libconcept{same_as}@>, value_type>; constexpr basic_const_iterator& operator++(); constexpr void operator++(int); @@ -5301,7 +5290,7 @@ \indexlibraryglobal{make_move_iterator}% \begin{itemdecl} template -constexpr move_iterator make_move_iterator(Iterator i); + constexpr move_iterator make_move_iterator(Iterator i); \end{itemdecl} \begin{itemdescr} @@ -7254,6 +7243,7 @@ \libheaderrefx{flat_map}{flat.map.syn}, \libheaderrefx{flat_set}{flat.set.syn}, \libheaderrefx{forward_list}{forward.list.syn}, +\libheaderrefx{inplace_vector}{inplace.vector.syn}, \libheaderref{list}, \libheaderrefx{map}{associative.map.syn}, \libheaderrefx{regex}{re.syn}, @@ -7461,7 +7451,7 @@ \indexlibrary{\idxcode{empty(C\& c)}}% \begin{itemdecl} -template [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty()); +template constexpr auto empty(const C& c) -> decltype(c.empty()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7471,7 +7461,7 @@ \indexlibrary{\idxcode{empty(T (\&array)[N])}}% \begin{itemdecl} -template [[nodiscard]] constexpr bool empty(const T (&array)[N]) noexcept; +template constexpr bool empty(const T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -7481,7 +7471,7 @@ \indexlibrary{\idxcode{empty(initializer_list)}}% \begin{itemdecl} -template [[nodiscard]] constexpr bool empty(initializer_list il) noexcept; +template constexpr bool empty(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum diff --git a/source/layout.tex b/source/layout.tex index b74849dd00..1f82bd20d9 100644 --- a/source/layout.tex +++ b/source/layout.tex @@ -10,7 +10,7 @@ %%-------------------------------------------------- %% set header and footer positions and sizes -\setheadfoot{\onelineskip}{2\onelineskip} +\setheadfoot{\onelineskip}{4\onelineskip} \setheaderspaces{*}{2\onelineskip}{*} %%-------------------------------------------------- diff --git a/source/lex.tex b/source/lex.tex index 03d086d26a..6cf011e432 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -83,8 +83,14 @@ \end{note} If an input file is determined to be a UTF-8 file, then it shall be a well-formed UTF-8 code unit sequence and -it is decoded to produce a sequence of Unicode scalar values. -A sequence of translation character set elements is then formed +it is decoded to produce a sequence of Unicode +\begin{footnote} +Unicode\textregistered\ is a registered trademark of Unicode, Inc. +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} +scalar values. +A sequence of translation character set elements\iref{lex.charset} is then formed by mapping each Unicode scalar value to the corresponding translation character set element. In the resulting sequence, @@ -96,8 +102,8 @@ For any other kind of input file supported by the implementation, characters are mapped, in an -\impldef{mapping physical source file characters to translation character set} manner, -to a sequence of translation character set elements\iref{lex.charset}, +\impldef{mapping input file characters to translation character set} manner, +to a sequence of translation character set elements, representing end-of-line indicators as new-line characters. \item @@ -108,7 +114,7 @@ immediately followed by zero or more whitespace characters other than new-line followed by a new-line character is deleted, splicing -physical source lines to form logical source lines. Only the last +physical source lines to form \defnx{logical source lines}{source line!logical}. Only the last backslash on any physical source line shall be eligible for being part of such a splice. \begin{note} @@ -134,7 +140,7 @@ would arise from a source file ending with an unclosed \tcode{/*} comment. \end{footnote} -Each comment is replaced by one space character. New-line characters are +Each comment\iref{lex.comment} is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of whitespace characters other than new-line is retained or replaced by one space character is unspecified. @@ -147,37 +153,40 @@ \grammarterm{r-char-sequence}, \grammarterm{h-char-sequence}, or \grammarterm{q-char-sequence}, -\grammarterm{universal-character-name}s are recognized and -replaced by the designated element of the translation character set. +\grammarterm{universal-character-name}s are recognized\iref{lex.universal.char} and +replaced by the designated element of the translation character set\iref{lex.charset}. The process of dividing a source file's characters into preprocessing tokens is context-dependent. \begin{example} See the handling of \tcode{<} within a \tcode{\#include} preprocessing -directive\iref{cpp.include}. +directive\iref{lex.header,cpp.include}. \end{example} -\item Preprocessing directives are executed, macro invocations are -expanded, and \tcode{_Pragma} unary operator expressions are executed. -A \tcode{\#include} preprocessing directive causes the named header or +\item The source file is analyzed as a \grammarterm{preprocessing-file}\iref{cpp.pre}. +Preprocessing directives\iref{cpp} are executed, macro invocations are +expanded\iref{cpp.replace}, and \tcode{_Pragma} unary operator expressions are executed\iref{cpp.pragma.op}. +A \tcode{\#include} preprocessing directive\iref{cpp.include} causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted. \item -For a sequence of two or more adjacent \grammarterm{string-literal} tokens, +For a sequence of two or more adjacent \grammarterm{string-literal} preprocessing tokens, a common \grammarterm{encoding-prefix} is determined as specified in \ref{lex.string}. -Each such \grammarterm{string-literal} token is then considered to have +Each such \grammarterm{string-literal} preprocessing token is then considered to have that common \grammarterm{encoding-prefix}. \item -Adjacent \grammarterm{string-literal} tokens are concatenated\iref{lex.string}. +\indextext{concatenation!string}% +Adjacent \grammarterm{string-literal} preprocessing tokens are concatenated\iref{lex.string}. -\item Whitespace characters separating tokens are no longer -significant. Each preprocessing token is converted into a -token\iref{lex.token}. The resulting tokens -constitute a \defn{translation unit} and +\item +Each preprocessing token is converted into a token\iref{lex.token}. +Whitespace characters separating tokens are no longer significant. +The resulting tokens constitute a \defn{translation unit} and are syntactically and -semantically analyzed and translated. +semantically analyzed as a \grammarterm{translation-unit}\iref{basic.link} and +translated. \begin{note} The process of analyzing and translating the tokens can occasionally result in one token being replaced by a sequence of other @@ -235,7 +244,9 @@ The program is ill-formed if any instantiation fails. -\item All external entity references are resolved. Library +\item +\indextext{linking}% +All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information @@ -243,7 +254,9 @@ \indextext{translation!phases|)} \end{enumerate} -\rSec1[lex.charset]{Character sets} +\rSec1[lex.char]{Characters}% + +\rSec2[lex.charset]{Character sets} \pnum \indextext{character set|(}% @@ -320,18 +333,75 @@ \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} \begin{bnf} \nontermdef{n-char-sequence}\br - n-char\br - n-char-sequence n-char + n-char \opt{n-char-sequence} \end{bnf} \begin{bnf} @@ -346,8 +416,7 @@ \begin{bnf} \nontermdef{simple-hexadecimal-digit-sequence}\br - hexadecimal-digit\br - simple-hexadecimal-digit-sequence hexadecimal-digit + hexadecimal-digit \opt{simple-hexadecimal-digit-sequence} \end{bnf} \begin{bnf} @@ -358,6 +427,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}, @@ -385,79 +470,28 @@ 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. +\rSec1[lex.comment]{Comments} \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. +\indextext{comment|(}% +\indextext{comment!\tcode{/*} \tcode{*/}}% +\indextext{comment!\tcode{//}}% +The characters \tcode{/*} start a comment, which terminates with the +characters \tcode{*/}. These comments do not nest. +\indextext{comment!\tcode{//}}% +The characters \tcode{//} start a comment, which terminates immediately before the +next new-line character. If there is a form-feed or a vertical-tab +character in such a comment, only whitespace characters shall appear +between it and the new-line that terminates the comment; no diagnostic +is required. \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. +The comment characters \tcode{//}, \tcode{/*}, +and \tcode{*/} have no special meaning within a \tcode{//} comment and +are treated just like other characters. Similarly, the comment +characters \tcode{//} and \tcode{/*} have no special meaning within a +\tcode{/*} comment. \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|)} +\indextext{comment|)} \rSec1[lex.pptoken]{Preprocessing tokens} @@ -478,11 +512,6 @@ \textnormal{each non-whitespace character that cannot be one of the above} \end{bnf} -\pnum -Each preprocessing token that is converted to a token\iref{lex.token} -shall have the lexical form of a keyword, an identifier, a literal, -or an operator or punctuator. - \pnum A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. @@ -517,6 +546,22 @@ between the quotation characters in a character literal or string literal. +\pnum +Each preprocessing token that is converted to a token\iref{lex.token} +shall have the lexical form of a keyword, an identifier, a literal, +or an operator or punctuator. + +\pnum +The \grammarterm{import-keyword} is produced +by processing an \keyword{import} directive\iref{cpp.import}, +the \grammarterm{module-keyword} is produced +by preprocessing a \keyword{module} directive\iref{cpp.module}, and +the \grammarterm{export-keyword} is produced +by preprocessing either of the previous two directives. +\begin{note} +None has any observable spelling. +\end{note} + \pnum If the input stream has been parsed into preprocessing tokens up to a given character: @@ -546,7 +591,7 @@ except that a \grammarterm{header-name}\iref{lex.header} is only formed \begin{itemize} \item -after the \tcode{include} or \tcode{import} preprocessing token in an +after the \tcode{include} or \tcode{import} preprocessing token in a \tcode{\#include}\iref{cpp.include} or \tcode{import}\iref{cpp.import} directive, or @@ -556,6 +601,7 @@ \end{itemize} \end{itemize} +\pnum \begin{example} \begin{codeblock} #define R "x" @@ -563,17 +609,6 @@ \end{codeblock} \end{example} -\pnum -The \grammarterm{import-keyword} is produced -by processing an \keyword{import} directive\iref{cpp.import}, -the \grammarterm{module-keyword} is produced -by preprocessing a \keyword{module} directive\iref{cpp.module}, and -the \grammarterm{export-keyword} is produced -by preprocessing either of the previous two directives. -\begin{note} -None has any observable spelling. -\end{note} - \pnum \begin{example} The program fragment \tcode{0xe+foo} is parsed as a @@ -596,111 +631,11 @@ \end{example} \indextext{token!preprocessing|)} -\rSec1[lex.digraph]{Alternative tokens} - -\pnum -\indextext{token!alternative|(}% -Alternative token representations are provided for some operators and -punctuators. -\begin{footnote} -\indextext{digraph}% -These include ``digraphs'' and additional reserved words. The term -``digraph'' (token consisting of two characters) is not perfectly -descriptive, since one of the alternative \grammarterm{preprocessing-token}s is -\tcode{\%:\%:} and of course several primary tokens contain two -characters. Nonetheless, those alternative tokens that aren't lexical -keywords are colloquially known as ``digraphs''. -\end{footnote} - -\pnum -In all respects of the language, each alternative token behaves the -same, respectively, as its primary token, except for its spelling. -\begin{footnote} -Thus the ``stringized'' values\iref{cpp.stringize} of -\tcode{[} and \tcode{<:} will be different, maintaining the source -spelling, but the tokens can otherwise be freely interchanged. -\end{footnote} -The set of alternative tokens is defined in -\tref{lex.digraph}. - -\begin{tokentable}{Alternative tokens}{lex.digraph}{Alternative}{Primary} -\tcode{<\%} & \tcode{\{} & -\keyword{and} & \tcode{\&\&} & -\keyword{and_eq} & \tcode{\&=} \\ \rowsep -\tcode{\%>} & \tcode{\}} & -\keyword{bitor} & \tcode{|} & -\keyword{or_eq} & \tcode{|=} \\ \rowsep -\tcode{<:} & \tcode{[} & -\keyword{or} & \tcode{||} & -\keyword{xor_eq} & \tcode{\caret=} \\ \rowsep -\tcode{:>} & \tcode{]} & -\keyword{xor} & \tcode{\caret} & -\keyword{not} & \tcode{!} \\ \rowsep -\tcode{\%:} & \tcode{\#} & -\keyword{compl} & \tcode{\~} & -\keyword{not_eq} & \tcode{!=} \\ \rowsep -\tcode{\%:\%:} & \tcode{\#\#} & -\keyword{bitand} & \tcode{\&} & - & \\ -\end{tokentable}% -\indextext{token!alternative|)} - -\rSec1[lex.token]{Tokens} - -\indextext{token|(}% -\begin{bnf} -\nontermdef{token}\br - identifier\br - keyword\br - literal\br - operator-or-punctuator -\end{bnf} - -\pnum -\indextext{\idxgram{token}}% -There are five kinds of tokens: identifiers, keywords, literals,% -\begin{footnote} -Literals include strings and character and numeric literals. -\end{footnote} -operators, and other separators. -\indextext{whitespace}% -Blanks, horizontal and vertical tabs, newlines, formfeeds, and comments -(collectively, ``whitespace''), as described below, are ignored except -as they serve to separate tokens. -\begin{note} -Whitespace can separate otherwise adjacent identifiers, keywords, numeric -literals, and alternative tokens containing alphabetic characters. -\end{note} -\indextext{token|)} - -\rSec1[lex.comment]{Comments} - -\pnum -\indextext{comment|(}% -\indextext{comment!\tcode{/*} \tcode{*/}}% -\indextext{comment!\tcode{//}}% -The characters \tcode{/*} start a comment, which terminates with the -characters \tcode{*/}. These comments do not nest. -\indextext{comment!\tcode{//}}% -The characters \tcode{//} start a comment, which terminates immediately before the -next new-line character. If there is a form-feed or a vertical-tab -character in such a comment, only whitespace characters shall appear -between it and the new-line that terminates the comment; no diagnostic -is required. -\begin{note} -The comment characters \tcode{//}, \tcode{/*}, -and \tcode{*/} have no special meaning within a \tcode{//} comment and -are treated just like other characters. Similarly, the comment -characters \tcode{//} and \tcode{/*} have no special meaning within a -\tcode{/*} comment. -\end{note} -\indextext{comment|)} - \rSec1[lex.header]{Header names} \indextext{header!name|(}% \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{header-name}\br \terminal{<} h-char-sequence \terminal{>}\br \terminal{"} q-char-sequence \terminal{"} @@ -708,8 +643,7 @@ \begin{bnf} \nontermdef{h-char-sequence}\br - h-char\br - h-char-sequence h-char + h-char \opt{h-char-sequence} \end{bnf} \begin{bnf} @@ -719,8 +653,7 @@ \begin{bnf} \nontermdef{q-char-sequence}\br - q-char\br - q-char-sequence q-char + q-char \opt{q-char-sequence} \end{bnf} \begin{bnf} @@ -729,16 +662,16 @@ \end{bnf} \pnum +The sequences in both forms of \grammarterm{header-name}{s} are mapped in an +\impldef{mapping header name to header or external source file} manner to headers or to +external source file names as specified in~\ref{cpp.include}. \begin{note} -Header name preprocessing tokens only appear within +Header name preprocessing tokens appear only within a \tcode{\#include} preprocessing directive, a \tcode{__has_include} preprocessing expression, or after certain occurrences of an \tcode{import} token (see~\ref{lex.pptoken}). \end{note} -The sequences in both forms of \grammarterm{header-name}{s} are mapped in an -\impldef{mapping header name to header or external source file} manner to headers or to -external source file names as specified in~\ref{cpp.include}. \pnum The appearance of either of the characters \tcode{'} or \tcode{\textbackslash} or of @@ -748,12 +681,12 @@ \tcode{/*}, or \tcode{//} in a \grammarterm{q-char-sequence} or an \grammarterm{h-char-sequence}} semantics, as is the appearance of the character \tcode{"} in an \grammarterm{h-char-sequence}. -\begin{footnote} +\begin{note} Thus, a sequence of characters that resembles an escape sequence can result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation. -\end{footnote} +\end{note} \indextext{header!name|)} \rSec1[lex.ppnumber]{Preprocessing numbers} @@ -785,7 +718,127 @@ a \grammarterm{floating-point-literal} token.% \indextext{number!preprocessing|)} +\rSec1[lex.operators]{Operators and punctuators} + +\pnum +\indextext{operator|(}% +\indextext{punctuator|(}% +The lexical representation of \Cpp{} programs includes a number of +preprocessing tokens that are used in the syntax of the preprocessor or +are converted into tokens for operators and punctuators: + +\begin{bnf} +\nontermdef{preprocessing-op-or-punc}\br + preprocessing-operator\br + operator-or-punctuator +\end{bnf} + +\begin{bnf} +%% Ed. note: character protrusion would misalign various operators. +\microtypesetup{protrusion=false} +\nontermdef{preprocessing-operator} \textnormal{one of}\br + \terminal{\# \ \ \ \ \ \ \ \#\# \ \ \ \ \ \ \%: \ \ \ \ \ \ \%:\%:} +\end{bnf} + +\begin{bnf} +\microtypesetup{protrusion=false} +\nontermdef{operator-or-punctuator} \textnormal{one of}\br + \terminal{\{ \ \ \ \ \ \ \ \} \ \ \ \ \ \ \ [ \ \ \ \ \ \ \ ] \ \ \ \ \ \ \ ( \ \ \ \ \ \ \ )}\br + \terminal{<\% \ \ \ \ \ \ \%> \ \ \ \ \ \ <: \ \ \ \ \ \ :> \ \ \ \ \ \ ; \ \ \ \ \ \ \ : \ \ \ \ \ \ \ ...}\br + \terminal{? \ \ \ \ \ \ \ :: \ \ \ \ \ \ . \ \ \ \ \ \ \ .* \ \ \ \ \ \ -> \ \ \ \ \ \ ->* \ \ \ \ \ \~}\br + \terminal{! \ \ \ \ \ \ \ + \ \ \ \ \ \ \ - \ \ \ \ \ \ \ * \ \ \ \ \ \ \ / \ \ \ \ \ \ \ \% \ \ \ \ \ \ \ \caret{} \ \ \ \ \ \ \ \& \ \ \ \ \ \ \ |}\br + \terminal{= \ \ \ \ \ \ \ += \ \ \ \ \ \ -= \ \ \ \ \ \ *= \ \ \ \ \ \ /= \ \ \ \ \ \ \%= \ \ \ \ \ \ \caret{}= \ \ \ \ \ \ \&= \ \ \ \ \ \ |=}\br + \terminal{== \ \ \ \ \ \ != \ \ \ \ \ \ < \ \ \ \ \ \ \ > \ \ \ \ \ \ \ <= \ \ \ \ \ \ >= \ \ \ \ \ \ <=> \ \ \ \ \ \&\& \ \ \ \ \ \ ||}\br + \terminal{<< \ \ \ \ \ \ >> \ \ \ \ \ \ <<= \ \ \ \ \ >>= \ \ \ \ \ ++ \ \ \ \ \ \ -- \ \ \ \ \ \ ,}\br + \terminal{\keyword{and} \ \ \ \ \ \keyword{or} \ \ \ \ \ \ \keyword{xor} \ \ \ \ \ \keyword{not} \ \ \ \ \ \keyword{bitand} \ \ \keyword{bitor} \ \ \ \keyword{compl}}\br + \terminal{\keyword{and_eq} \ \ \keyword{or_eq} \ \ \ \keyword{xor_eq} \ \ \keyword{not_eq}} +\end{bnf} + +Each \grammarterm{operator-or-punctuator} is converted to a single token +in translation phase 7\iref{lex.phases}.% +\indextext{punctuator|)}% +\indextext{operator|)} + +\rSec1[lex.digraph]{Alternative tokens} + +\pnum +\indextext{token!alternative|(}% +Alternative token representations are provided for some operators and +punctuators. +\begin{footnote} +\indextext{digraph}% +These include ``digraphs'' and additional reserved words. The term +``digraph'' (token consisting of two characters) is not perfectly +descriptive, since one of the alternative \grammarterm{preprocessing-token}s is +\tcode{\%:\%:} and of course several primary tokens contain two +characters. Nonetheless, those alternative tokens that aren't lexical +keywords are colloquially known as ``digraphs''. +\end{footnote} + +\pnum +In all respects of the language, each alternative token behaves the +same, respectively, as its primary token, except for its spelling. +\begin{footnote} +Thus the ``stringized'' values\iref{cpp.stringize} of +\tcode{[} and \tcode{<:} will be different, maintaining the source +spelling, but the tokens can otherwise be freely interchanged. +\end{footnote} +The set of alternative tokens is defined in +\tref{lex.digraph}. + +\begin{tokentable}{Alternative tokens}{lex.digraph}{Alternative}{Primary} +\tcode{<\%} & \tcode{\{} & +\keyword{and} & \tcode{\&\&} & +\keyword{and_eq} & \tcode{\&=} \\ \rowsep +\tcode{\%>} & \tcode{\}} & +\keyword{bitor} & \tcode{|} & +\keyword{or_eq} & \tcode{|=} \\ \rowsep +\tcode{<:} & \tcode{[} & +\keyword{or} & \tcode{||} & +\keyword{xor_eq} & \tcode{\caret=} \\ \rowsep +\tcode{:>} & \tcode{]} & +\keyword{xor} & \tcode{\caret} & +\keyword{not} & \tcode{!} \\ \rowsep +\tcode{\%:} & \tcode{\#} & +\keyword{compl} & \tcode{\~} & +\keyword{not_eq} & \tcode{!=} \\ \rowsep +\tcode{\%:\%:} & \tcode{\#\#} & +\keyword{bitand} & \tcode{\&} & + & \\ +\end{tokentable}% +\indextext{token!alternative|)} + +\rSec1[lex.token]{Tokens} + +\indextext{token|(}% +\begin{bnf} +\nontermdef{token}\br + identifier\br + keyword\br + literal\br + operator-or-punctuator +\end{bnf} + +\pnum +\indextext{\idxgram{token}}% +There are five kinds of tokens: identifiers, keywords, literals,% +\begin{footnote} +Literals include strings and character and numeric literals. +\end{footnote} +operators, and other separators. +\indextext{whitespace}% +Blanks, horizontal and vertical tabs, newlines, formfeeds, and comments +(collectively, ``whitespace''), as described below, are ignored except +as they serve to separate tokens. +\begin{note} +Whitespace can separate otherwise adjacent identifiers, keywords, numeric +literals, and alternative tokens containing alphabetic characters. +\end{note} +\indextext{token|)} + \rSec1[lex.name]{Identifiers} +\indextext{XID_Start}% +\indextext{XID_Continue}% \indextext{identifier|(}% \begin{bnf} @@ -824,8 +877,7 @@ \indextext{name!length of}% \indextext{name}% \begin{note} -The character properties XID_Start and XID_Continue are Derived Core Properties -as described by \UAX{44} of the Unicode Standard. +The character properties XID_Start and XID_Continue are described by \UAX{44} of the Unicode Standard. \begin{footnote} On systems in which linkers cannot accept extended characters, an encoding of the \grammarterm{universal-character-name} can be used in @@ -860,6 +912,8 @@ \indextext{\idxcode{final}}% \indextext{\idxcode{module}}% \indextext{\idxcode{override}}% +\indextext{\idxcode{replaceable_if_eligible}}% +\indextext{\idxcode{trivially_relocatable_if_eligible}}% The identifiers in \tref{lex.name.special} have a special meaning when appearing in a certain context. When referred to in the grammar, these identifiers are used explicitly rather than using the \grammarterm{identifier} grammar production. @@ -869,13 +923,14 @@ \begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special} {llll} -\keyword{final} \\ -\columnbreak -\keyword{import} \\ -\columnbreak -\keyword{module} \\ -\columnbreak -\keyword{override} \\ +\keyword{final} \\ +\keyword{override} \\\columnbreak +\keyword{import} \\ +\keyword{module} \\\columnbreak +\keyword{post} \\ +\keyword{pre} \\\columnbreak +\keyword{replaceable_if_eligible} \\ +\keyword{trivially_relocatable_if_eligible} \\ \end{multicolfloattable} \pnum @@ -893,7 +948,9 @@ \tcode{\unun} \indextext{character!underscore}% or begins with an underscore followed by -an uppercase letter +an uppercase letter, +other than those specified in this document +(for example, \xname{cplusplus}\iref{cpp.predefined}), \indextext{uppercase}% is reserved to the implementation for any use. \item @@ -947,6 +1004,7 @@ \keyword{constinit} \\ \keyword{const_cast} \\ \keyword{continue} \\ +\keyword{contract_assert} \\ \keyword{co_await} \\ \keyword{co_return} \\ \keyword{co_yield} \\ @@ -960,8 +1018,8 @@ \keyword{enum} \\ \keyword{explicit} \\ \keyword{export} \\ -\keyword{extern} \\ \columnbreak +\keyword{extern} \\ \keyword{false} \\ \keyword{float} \\ \keyword{for} \\ @@ -978,8 +1036,8 @@ \keyword{nullptr} \\ \keyword{operator} \\ \keyword{private} \\ -\keyword{protected} \\ \columnbreak +\keyword{protected} \\ \keyword{public} \\ \keyword{register} \\ \keyword{reinterpret_cast} \\ @@ -996,8 +1054,8 @@ \keyword{template} \\ \keyword{this} \\ \keyword{thread_local} \\ -\keyword{throw} \\ \columnbreak +\keyword{throw} \\ \keyword{true} \\ \keyword{try} \\ \keyword{typedef} \\ @@ -1028,47 +1086,6 @@ \indextext{keyword|)}% -\rSec1[lex.operators]{Operators and punctuators} - -\pnum -\indextext{operator|(}% -\indextext{punctuator|(}% -The lexical representation of \Cpp{} programs includes a number of -preprocessing tokens that are used in the syntax of the preprocessor or -are converted into tokens for operators and punctuators: - -\begin{bnf} -\nontermdef{preprocessing-op-or-punc}\br - preprocessing-operator\br - operator-or-punctuator -\end{bnf} - -\begin{bnf} -%% Ed. note: character protrusion would misalign various operators. -\microtypesetup{protrusion=false}\obeyspaces -\nontermdef{preprocessing-operator} \textnormal{one of}\br - \terminal{\# \#\# \%: \%:\%:} -\end{bnf} - -\begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces -\nontermdef{operator-or-punctuator} \textnormal{one of}\br - \terminal{\{ \} [ ] ( )}\br - \terminal{<: :> <\% \%> ; : ...}\br - \terminal{? :: . .* -> ->* \~}\br - \terminal{! + - * / \% \caret{} \& |}\br - \terminal{= += -= *= /= \%= \caret{}= \&= |=}\br - \terminal{== != < > <= >= <=> \&\& ||}\br - \terminal{<< >> <<= >>= ++ -- ,}\br - \terminal{\keyword{and} \keyword{or} \keyword{xor} \keyword{not} \keyword{bitand} \keyword{bitor} \keyword{compl}}\br - \terminal{\keyword{and_eq} \keyword{or_eq} \keyword{xor_eq} \keyword{not_eq}} -\end{bnf} - -Each \grammarterm{operator-or-punctuator} is converted to a single token -in translation phase 7\iref{lex.phases}.% -\indextext{punctuator|)}% -\indextext{operator|)} - \rSec1[lex.literal]{Literals}% \indextext{literal|(} @@ -1080,8 +1097,7 @@ There are several kinds of literals. \begin{footnote} The term ``literal'' generally designates, in this -document, those tokens that are called ``constants'' in -ISO C. +document, those tokens that are called ``constants'' in C. \end{footnote} \begin{bnf} @@ -1207,7 +1223,7 @@ \grammarterm{octal-digit}s, \grammarterm{digit}s, or \grammarterm{hexadecimal-digit}s -is interpreted as a base $N$ integer as shown in table \tref{lex.icon.base}; +is interpreted as a base $N$ integer as shown in \tref{lex.icon.base}; the lexically first digit of the sequence of digits is the most significant. \begin{note} The prefix and any optional separating single quotes are ignored @@ -1366,8 +1382,7 @@ \begin{bnf} \nontermdef{c-char-sequence}\br - c-char\br - c-char-sequence c-char + c-char \opt{c-char-sequence} \end{bnf} \begin{bnf} @@ -1408,8 +1423,7 @@ \begin{bnf} \nontermdef{simple-octal-digit-sequence}\br - octal-digit\br - simple-octal-digit-sequence octal-digit + octal-digit \opt{simple-octal-digit-sequence} \end{bnf} \begin{bnf} @@ -1417,7 +1431,7 @@ \terminal{\textbackslash} octal-digit\br \terminal{\textbackslash} octal-digit octal-digit\br \terminal{\textbackslash} octal-digit octal-digit octal-digit\br - \terminal{\textbackslash o\{} simple-octal-digit-sequence \terminal{\}}\br + \terminal{\textbackslash o\{} simple-octal-digit-sequence \terminal{\}} \end{bnf} \begin{bnf} @@ -1466,8 +1480,8 @@ \begin{floattable}{Character literals}{lex.ccon.literal} {l|l|l|l|l} \topline -Encoding & Kind & Type & Associated char- & Example \\ -prefix & & & acter encoding & \\ +\lhdr{Encoding} & \chdr{Kind} & \chdr{Type} & \chdr{Associated char-} & \rhdr{Example} \\ +\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{acter encoding} & \\ \capsep none & \defnx{ordinary character literal}{literal!character!ordinary} & @@ -1568,7 +1582,7 @@ is specified in \tref{lex.ccon.esc}. \begin{note} Using an escape sequence for a question mark -is supported for compatibility with ISO \CppXIV{} and ISO C. +is supported for compatibility with \CppXIV{} and C. \end{note} \begin{floattable}{Simple escape sequences}{lex.ccon.esc} @@ -1674,7 +1688,7 @@ \topline \lhdr{\grammarterm{floating-point-suffix}} & \rhdr{type} \\ \capsep none & \keyword{double} \\ -\tcode{f} or \tcode{F} & \keyword {float} \\ +\tcode{f} or \tcode{F} & \keyword{float} \\ \tcode{l} or \tcode{L} & \keyword{long} \keyword{double} \\ \tcode{f16} or \tcode{F16} & \tcode{std::float16_t} \\ \tcode{f32} or \tcode{F32} & \tcode{std::float32_t} \\ @@ -1737,8 +1751,7 @@ \begin{bnf} \nontermdef{s-char-sequence}\br - s-char\br - s-char-sequence s-char + s-char \opt{s-char-sequence} \end{bnf} \begin{bnf} @@ -1761,8 +1774,7 @@ \begin{bnf} \nontermdef{r-char-sequence}\br - r-char\br - r-char-sequence r-char + r-char \opt{r-char-sequence} \end{bnf} \begin{bnf} @@ -1773,8 +1785,7 @@ \begin{bnf} \nontermdef{d-char-sequence}\br - d-char\br - d-char-sequence d-char + d-char \opt{d-char-sequence} \end{bnf} \begin{bnf} @@ -1800,14 +1811,16 @@ are determined by its encoding prefix and sequence of \grammarterm{s-char}s or \grammarterm{r-char}s as defined by \tref{lex.string.literal} -where $n$ is the number of encoded code units as described below. +where $n$ is the number of encoded code units +that would result from an evaluation of the \grammarterm{string-literal} +(see below). \begin{floattable}{String literals}{lex.string.literal} {llp{2.6cm}p{2.3cm}p{4.7cm}} \topline -Encoding & Kind & Type & Associated & Examples \\ -prefix & & & character & \\ - & & & encoding & \\ +\lhdr{Enco-} & \chdr{Kind} & \chdr{Type} & \chdr{Associated} & \rhdr{Examples} \\ +\lhdr{ding} & \chdr{} & \chdr{} & \chdr{character} & \rhdr{} \\ +\lhdr{prefix} & \chdr{} & \chdr{} & \chdr{encoding} & \rhdr{} \\ \capsep none & \defnx{ordinary string literal}{literal!string!ordinary} & @@ -1894,16 +1907,11 @@ \pnum \indextext{concatenation!string}% -The common \grammarterm{encoding-prefix} -for a sequence of adjacent \grammarterm{string-literal}s -is determined pairwise as follows: -If two \grammarterm{string-literal}{s} have -the same \grammarterm{encoding-prefix}, -the common \grammarterm{encoding-prefix} is that \grammarterm{encoding-prefix}. -If one \grammarterm{string-literal} has no \grammarterm{encoding-prefix}, -the common \grammarterm{encoding-prefix} is that -of the other \grammarterm{string-literal}. -Any other combinations are ill-formed. +The \grammarterm{string-literal}{s} in +any sequence of adjacent \grammarterm{string-literal}{s} +shall have at most one unique \grammarterm{encoding-prefix} among them. +The common \grammarterm{encoding-prefix} of the sequence is +that \grammarterm{encoding-prefix}, if any. \begin{note} A \grammarterm{string-literal}'s rawness has no effect on the determination of the common \grammarterm{encoding-prefix}. @@ -2221,7 +2229,7 @@ and let \placeholder{len} be the number of code units in \placeholder{str} (i.e., its length excluding the terminating null character). If \placeholder{S} contains a literal operator template with -a non-type template parameter for which \placeholder{str} is +a constant template parameter for which \placeholder{str} is a well-formed \grammarterm{template-argument}, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index c4eef90633..61fcbded40 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -32,21 +32,21 @@ \ref{mem} & Memory management library \\ \ref{meta} & Metaprogramming library \\ \ref{utilities} & General utilities library \\ -\ref{strings} & Strings library \\ \ref{containers} & Containers library \\ \ref{iterators} & Iterators library \\ \ref{ranges} & Ranges library \\ \ref{algorithms} & Algorithms library \\ +\ref{strings} & Strings library \\ +\ref{text} & Text processing library \\ \ref{numerics} & Numerics library \\ \ref{time} & Time library \\ -\ref{localization} & Localization library \\ \ref{input.output} & Input/output library \\ -\ref{re} & Regular expressions library \\ \ref{thread} & Concurrency support library \\ +\ref{exec} & Execution control library \\ \end{floattable} \pnum -The operating system interface described in ISO/IEC/IEEE 9945:2009 is +The operating system interface described in \IsoPosix{} is hereinafter called \defn{POSIX}. \pnum @@ -82,8 +82,13 @@ such as tuples and function wrappers. \pnum -The strings library\iref{strings} provides support for manipulating text represented -as sequences of type \tcode{char}, +The containers\iref{containers}, iterators\iref{iterators}, ranges\iref{ranges}, +and algorithms\iref{algorithms} libraries provide a \Cpp{} program with access +to a subset of the most widely used algorithms and data structures. + +\pnum +The strings library\iref{strings} provides support +for manipulating sequences of type \tcode{char}, sequences of type \keyword{char8_t}, sequences of type \keyword{char16_t}, sequences of type \keyword{char32_t}, @@ -91,9 +96,9 @@ and sequences of any other character-like type. \pnum -The containers\iref{containers}, iterators\iref{iterators}, ranges\iref{ranges}, -and algorithms\iref{algorithms} libraries provide a \Cpp{} program with access -to a subset of the most widely used algorithms and data structures. +The text processing library\iref{text} provides support for text processing, +including formatting, internationalization support and +regular expression matching and searching. \pnum The numerics library\iref{numerics} provides @@ -110,10 +115,6 @@ The time library\iref{time} provides generally useful time utilities. -\pnum -The localization library\iref{localization} provides extended internationalization -support for text processing. - \pnum The input/output library\iref{input.output} provides the \tcode{iostream} @@ -121,14 +122,15 @@ They can be used with other elements of the library, particularly strings, locales, and iterators. -\pnum -The regular expressions library\iref{re} provides regular expression matching and searching. - \pnum The concurrency support library\iref{thread} provides components to create and manage threads, including atomic operations, mutual exclusion, and interthread communication. +\pnum +The execution control library\iref{exec} provides components +supporting execution of function objects. + \rSec1[library.c]{The C standard library} \pnum @@ -144,8 +146,8 @@ may be different from the signatures in the C standard library, and additional overloads may be declared in this document, but the behavior and the preconditions -(including any preconditions implied by the use of an -ISO C \tcode{restrict} qualifier) +(including any preconditions implied by the use of +a C \tcode{restrict} qualifier) are the same unless otherwise stated. \pnum @@ -161,7 +163,7 @@ to the extent applicable to the floating-point types\iref{basic.fundamental} that are parameter types of the called function. \begin{note} -Annex F specifies +\IsoC{}, Annex F specifies the conditions under which floating-point exceptions are raised and the behavior when NaNs and/or infinities are passed as arguments. \end{note} @@ -368,9 +370,32 @@ \item \expects -the conditions -that the function assumes to hold whenever it is called; +conditions that the function assumes to hold whenever it is called; violation of any preconditions results in undefined behavior. +\begin{example} +An implementation can express some such conditions +via the use of a contract assertion, +such as a precondition assertion\iref{dcl.contract.func}. +\end{example} + +\item +\hardexpects +conditions that the function assumes to hold whenever it is called. +\begin{itemize} +\item +When invoking the function in a hardened implementation, +prior to any other observable side effects of the function, +one or more contract assertions +whose predicates are as described in the hardened precondition +are evaluated with a checking semantic\iref{basic.contract.eval}. +If any of these assertions is evaluated with a non-terminating semantic +and the contract-violation handler returns, +the program has undefined behavior. +\item +When invoking the function in a non-hardened implementation, +if any hardened precondition is violated, +the program has undefined behavior. +\end{itemize} \item \effects @@ -384,12 +409,17 @@ \ensures the conditions (sometimes termed observable results) established by the function. +\begin{example} +An implementation can express some such conditions +via the use of a contract assertion, +such as a postcondition assertion\iref{dcl.contract.func}. +\end{example} \item \result for a \grammarterm{typename-specifier}, a description of the named type; for an \grammarterm{expression}, -a description of the type of the expression; +a description of the type and value category of the expression; the expression is an lvalue if the type is an lvalue reference type, an xvalue if the type is an rvalue reference type, and a prvalue otherwise. @@ -422,9 +452,18 @@ If \tcode{F}'s semantics specifies any \Fundescx{Constraints} or \Fundescx{Mandates} elements, then those requirements are logically imposed prior to the \term{equivalent-to} semantics. Next, the semantics of the code sequence are determined by the -\Fundescx{Constraints}, \Fundescx{Mandates}, \Fundescx{Preconditions}, \Fundescx{Effects}, -\Fundescx{Synchronization}, \Fundescx{Postconditions}, \Fundescx{Returns}, \Fundescx{Throws}, -\Fundescx{Complexity}, \Fundescx{Remarks}, and \Fundescx{Error conditions} +\Fundescx{Constraints}, +\Fundescx{Mandates}, +\Fundescx{Preconditions}, +\Fundescx{Hardened preconditions}, +\Fundescx{Effects}, +\Fundescx{Synchronization}, +\Fundescx{Postconditions}, +\Fundescx{Returns}, +\Fundescx{Throws}, +\Fundescx{Complexity}, +\Fundescx{Remarks}, and +\Fundescx{Error conditions} specified for the function invocations contained in the code sequence. The value returned from \tcode{F} is specified by \tcode{F}'s \Fundescx{Returns} element, or if \tcode{F} has no \Fundescx{Returns} element, @@ -525,6 +564,14 @@ } \end{codeblock} +\pnum +An object \tcode{dst} is said to be \defn{decay-copied from} +a subexpression \tcode{src} +if the type of \tcode{dst} is +\begin{codeblock} +decay_t +\end{codeblock} and \tcode{dst} is copy-initialized from \tcode{src}. + \rSec3[type.descriptions]{Type descriptions} \rSec4[type.descriptions.general]{General} @@ -846,9 +893,40 @@ \item \tcode{std::move(as_const(p))(args...)} \end{itemize} +\rSec3[alg.func.obj]{Algorithm function objects} + \pnum -Each customization point object type constrains its return type to model a -particular concept. +An \defn{algorithm function object} is +a customization point object\iref{customization.point.object} +that is specified as one or more overloaded function templates. +The name of these function templates designates +the corresponding algorithm function object. + +\pnum +For an algorithm function object \tcode{o}, +let $S$ be the corresponding set of function templates. +Then for any sequence of arguments $\tcode{args} \dotsc$, +$\tcode{o(args} \dotsc \tcode{)}$ is expression-equivalent to +$\tcode{s(args} \dotsc \tcode{)}$, +where the result of name lookup for \tcode{s} is the overload set $S$. +\begin{note} +Algorithm function objects are not found by +argument-dependent name lookup\iref{basic.lookup.argdep}. +When found by unqualified name lookup\iref{basic.lookup.unqual} +for the \grammarterm{postfix-expression} in a function call\iref{expr.call}, +they inhibit argument-dependent name lookup. +\begin{example} +\begin{codeblock} +void foo() { + using namespace std::ranges; + std::vector vec{1,2,3}; + find(begin(vec), end(vec), 2); // \#1 +} +\end{codeblock} +The function call expression at \#1 invokes \tcode{std::ranges::find}, +not \tcode{std::find}. +\end{example} +\end{note} \rSec3[functions.within.classes]{Functions within classes} @@ -951,8 +1029,9 @@ \indextext{entity!freestanding item}% \indextext{deduction guide!freestanding item}% \indextext{\idxgram{typedef-name}!freestanding item}% -An entity, deduction guide, or \grammarterm{typedef-name} is -a freestanding item if it is: +An entity, deduction guide, or \grammarterm{typedef-name} +is a freestanding item if its introducing declaration is not followed by +a comment that includes \textit{hosted}, and is: \begin{itemize} \item introduced by a declaration that is a freestanding item, \item a member of a freestanding item other than a namespace, @@ -1070,7 +1149,8 @@ \pnum Whenever an unqualified name other than -\tcode{swap}, \tcode{make_error_code}, \tcode{make_error_condition}, or +\tcode{swap}, \tcode{make_error_code}, \tcode{make_error_condition}, +\tcode{from_stream}, or \tcode{submdspan_mapping} is used in the specification of a declaration \tcode{D} in \ref{\firstlibchapter} through \ref{\lastlibchapter} or \ref{depr}, @@ -1094,7 +1174,8 @@ in an overload resolution context for swappable values\iref{swappable.requirements}. The meanings of the unqualified names -\tcode{make_error_code}, \tcode{make_error_condition}, and +\tcode{make_error_code}, \tcode{make_error_condition}, +\tcode{from_stream}, and \tcode{submdspan_mapping} are established as-if by performing argument-dependent lookup\iref{basic.lookup.argdep}. @@ -1131,6 +1212,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1141,14 +1223,16 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\columnbreak \tcode{} \\ +\columnbreak \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1164,8 +1248,8 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\columnbreak \tcode{} \\ +\columnbreak \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1182,13 +1266,14 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\columnbreak \tcode{} \\ +\columnbreak \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1444,12 +1529,19 @@ \pnum The named module \tcode{std.compat} exports the same declarations as the named module \tcode{std}, and -additionally exports declarations in the global namespace +additionally exports +\begin{itemize} +\item +declarations in the global namespace corresponding to the declarations in namespace \tcode{std} that are provided by the \Cpp{} headers for C library facilities~(\tref{headers.cpp.c}), except the explicitly excluded declarations -described in \ref{support.c.headers.other}. +described in \ref{support.c.headers.other} and +\item +declarations provided by +the headers \libheaderref{stdbit.h} and \libheaderref{stdckdint.h}. +\end{itemize} \pnum It is unspecified to which module a declaration in the standard library @@ -1507,18 +1599,20 @@ \ref{support.limits} & Implementation properties & \tcode{}, \tcode{}, \tcode{}, \\ & & \tcode{} \\ \rowsep -\ref{cstdint.syn} & Integer types & \tcode{} \\ \rowsep +\ref{cstdint.syn} & Integer types & \tcode{} \\ \rowsep \ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.srcloc} & Source location & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{cmp} & Comparisons & \tcode{} \\ \rowsep +\ref{support.contract} & Contract-violation handling & \tcode{} \\ \rowsep \ref{support.coroutine} & Coroutines support & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ \rowsep \ref{concepts} & Concepts library & \tcode{} \\ \rowsep \ref{errno} & Error numbers & \tcode{} \\ \rowsep \ref{syserr} & System error support & \tcode{} \\ \rowsep +\ref{debugging} & Debugging & \tcode{} \\ \rowsep \ref{memory} & Memory & \tcode{} \\ \rowsep \ref{type.traits} & Type traits & \tcode{} \\ \rowsep \ref{ratio} & Compile-time rational arithmetic & \tcode{} \\ \rowsep @@ -1528,18 +1622,20 @@ \ref{variant} & Variants & \tcode{} \\ \rowsep \ref{expected} & Expected objects & \tcode{} \\ \rowsep \ref{function.objects} & Function objects & \tcode{} \\ \rowsep -\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ \rowsep -\ref{debugging} & Debugging & \tcode{} \\ \rowsep -\ref{string.view} & String view classes & \tcode{} \\ \rowsep -\ref{string.classes} & String classes & \tcode{} \\ \rowsep -\ref{c.strings} & Null-terminated sequence utilities & \tcode{}, \tcode{} \\ \rowsep \ref{array} & Class template \tcode{array} & \tcode{} \\ \rowsep +\ref{inplace.vector} & Class template \tcode{inplace_vector} & \tcode{} \\ \rowsep \ref{views.contiguous} & Contiguous access & \tcode{} \\ \rowsep \ref{views.multidim} & Multidimensional access & \tcode{} \\ \rowsep \ref{iterators} & Iterators library & \tcode{} \\ \rowsep \ref{ranges} & Ranges library & \tcode{} \\ \rowsep \ref{algorithms} & Algorithms library & \tcode{}, \tcode{} \\ \rowsep +\ref{execpol} & Execution policies & \tcode{} \\ \rowsep +\ref{string.view} & String view classes & \tcode{} \\ \rowsep +\ref{string.classes} & String classes & \tcode{} \\ \rowsep +\ref{c.strings} & Null-terminated sequence utilities & \tcode{}, \tcode{} \\ \rowsep +\ref{charconv} & Primitive numeric conversions & \tcode{} \\ \rowsep +\ref{rand} & Random number generation & \tcode{} \\ \rowsep \ref{c.math} & Mathematical functions for floating-point types & \tcode{} \\ \rowsep \ref{atomics} & Atomics & \tcode{} \\ \rowsep \end{libsumtab} @@ -1822,7 +1918,7 @@ denote an expression of type \tcode{U}. \pnum -An object \tcode{t} is \defn{swappable with} an object \tcode{u} if and only if: +An object \tcode{t} is \defn{swappable with} an object \tcode{u} if and only if \begin{itemize} \item the expressions \tcode{swap(t, u)} and \tcode{swap(u, t)} are valid when evaluated in the context described below, and @@ -1924,7 +2020,7 @@ \pnum A \oldconcept{NullablePointer} type is a pointer-like type that supports null values. -A type \tcode{P} meets the \oldconcept{\-Nullable\-Pointer} requirements if: +A type \tcode{P} meets the \oldconcept{\-Nullable\-Pointer} requirements if \begin{itemize} \item \tcode{P} meets the \oldconcept{EqualityComparable}, \oldconcept{DefaultConstructible}, \oldconcept{CopyConstructible}, \oldconcept{\-Copy\-Assign\-able}, @@ -2000,7 +2096,7 @@ \rSec3[hash.requirements]{\oldconcept{Hash} requirements} \pnum -A type \tcode{H} meets the \defnoldconcept{Hash} requirements if: +A type \tcode{H} meets the \defnoldconcept{Hash} requirements if \begin{itemize} \item it is a function object type\iref{function.objects}, \item it meets the \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}) and @@ -2048,13 +2144,13 @@ difference, the type of the size of objects in this allocation model, as well as the memory allocation and deallocation primitives for it. All of the string types\iref{strings}, -containers\iref{containers} (except \tcode{array}), +containers\iref{containers} (except \tcode{array} and \tcode{inplace_vector}), string buffers and string streams\iref{input.output}, and \tcode{match_results}\iref{re} are parameterized in terms of allocators. \pnum -In subclause \ref{allocator.requirements}, +In \ref{allocator.requirements}, \begin{itemize} \item \tcode{T}, \tcode{U}, \tcode{C} denote @@ -2222,7 +2318,7 @@ \end{itemdescr} \begin{itemdecl} -typename X::template rebind::other +typename X::rebind::other \end{itemdecl} \begin{itemdescr} @@ -2850,6 +2946,22 @@ \end{codeblock} \end{example} +\pnum +The following exposition-only concept defines +the minimal requirements on an Allocator type. +\begin{codeblock} +template +concept @\defexposconcept{simple-allocator}@ = + requires(Alloc alloc, size_t n) { + { *alloc.allocate(n) } -> @\libconcept{same_as}@; + { alloc.deallocate(alloc.allocate(n), n) }; + } && + @\libconcept{copy_constructible}@ && + @\libconcept{equality_comparable}@; +\end{codeblock} +A type \tcode{Alloc} models \exposconcept{simple-allocator} +if it meets the requirements of \ref{allocator.requirements.general}. + \rSec4[allocator.requirements.completeness]{Allocator completeness requirements} \pnum @@ -2981,7 +3093,7 @@ or to a namespace within namespace \tcode{posix} unless otherwise specified. The namespace \tcode{posix} is reserved for use by -ISO/IEC/IEEE 9945 and other POSIX standards. +\IsoPosixUndated{} and other POSIX standards. \rSec4[namespace.future]{Namespaces for future standardization} @@ -3284,72 +3396,13 @@ \rSec3[replacement.functions]{Replacement functions} \pnum -\indextext{definition!alternate}% +If a function defined in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} -describe the behavior of numerous functions defined by -the \Cpp{} standard library. -Under some circumstances, -\indextext{library!\Cpp{} standard}% -however, certain of these function descriptions also apply to replacement functions defined -in the program. - -\pnum -A \Cpp{} program may provide the definition for any of the following -dynamic memory allocation function signatures declared in header -\tcode{}\iref{basic.stc.dynamic,new.syn}: - -\indextext{\idxcode{new}!\idxcode{operator}!replaceable}% -\indexlibrarymember{new}{operator}% -\begin{codeblock} -operator new(std::size_t) -operator new(std::size_t, std::align_val_t) -operator new(std::size_t, const std::nothrow_t&) -operator new(std::size_t, std::align_val_t, const std::nothrow_t&) -\end{codeblock}% -\indextext{\idxcode{delete}!\idxcode{operator}!replaceable}% -\indexlibrarymember{delete}{operator}% -\begin{codeblock} -operator delete(void*) -operator delete(void*, std::size_t) -operator delete(void*, std::align_val_t) -operator delete(void*, std::size_t, std::align_val_t) -operator delete(void*, const std::nothrow_t&) -operator delete(void*, std::align_val_t, const std::nothrow_t&) -\end{codeblock}% -\indextext{\idxcode{new}!\idxcode{operator}!replaceable}% -\indexlibrarymember{new}{operator}% -\begin{codeblock} -operator new[](std::size_t) -operator new[](std::size_t, std::align_val_t) -operator new[](std::size_t, const std::nothrow_t&) -operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) -\end{codeblock}% -\indextext{\idxcode{delete}!\idxcode{operator}!replaceable}% -\indexlibrarymember{delete}{operator}% -\begin{codeblock} -operator delete[](void*) -operator delete[](void*, std::size_t) -operator delete[](void*, std::align_val_t) -operator delete[](void*, std::size_t, std::align_val_t) -operator delete[](void*, const std::nothrow_t&) -operator delete[](void*, std::align_val_t, const std::nothrow_t&) -\end{codeblock} - -\pnum -A \Cpp{} program may provide the definition of -the following function signature declared in header \libheaderref{debugging}: -\begin{codeblock} -bool std::is_debugger_present() noexcept -\end{codeblock} +is specified as replaceable\iref{dcl.fct.def.replace}, +the description of function semantics apply +to both the default version defined by the \Cpp{} standard library and +the replacement function defined by the program. -\pnum -The program's definitions are used instead of the default versions supplied by -the implementation\iref{new.delete}. -Such replacement occurs prior to program startup\iref{basic.def.odr,basic.start}. -\indextext{startup!program}% -The program's declarations shall not be specified as -\keyword{inline}. -No diagnostic is required. \rSec3[handler.functions]{Handler functions} @@ -3406,7 +3459,7 @@ \begin{itemize} \item -For replacement functions\iref{new.delete}, if the installed replacement function does not +For replacement functions\iref{replacement.functions}, if the installed replacement function does not implement the semantics of the applicable \required paragraph. @@ -3534,12 +3587,18 @@ Subclause \ref{conforming} describes the constraints upon, and latitude of, implementations of the \Cpp{} standard library. \pnum -An implementation's use of headers is discussed in~\ref{res.on.headers}, its use -of macros in~\ref{res.on.macro.definitions}, non-member functions -in~\ref{global.functions}, member functions in~\ref{member.functions}, data race -avoidance in~\ref{res.on.data.races}, access specifiers -in~\ref{protection.within.classes}, class derivation in~\ref{derivation}, and -exceptions in~\ref{res.on.exception.handling}. +An implementation's use of +\begin{itemize} +\item headers is discussed in~\ref{res.on.headers}, +\item macros in~\ref{res.on.macro.definitions}, +\item non-member functions in~\ref{global.functions}, +\item member functions in~\ref{member.functions}, +\item data race avoidance in~\ref{res.on.data.races}, +\item access specifiers in~\ref{protection.within.classes}, +\item class derivation in~\ref{derivation}, +\item exceptions in~\ref{res.on.exception.handling}, and +\item contract assertions in~\ref{res.contract.assertions}. +\end{itemize} \rSec3[res.on.headers]{Headers} @@ -3759,6 +3818,28 @@ side effects. \end{note} +\rSec3[library.class.props]{Properties of library classes} + +\pnum +Unless explicitly stated otherwise, it is unspecified whether any class +described in \ref{\firstlibchapter} through \ref{\lastlibchapter} and +\ref{depr} is a trivially copyable class, a standard-layout class, or an +implicit-lifetime class\iref{class.prop}. + +\pnum +Unless explicitly stated otherwise, it is unspecified whether any class for +which trivial relocation (i.e., the effects of +\tcode{trivially_relocate}\iref{obj.lifetime}) would be semantically equivalent +to move-construction of the destination object followed by destruction of the +source object is a trivially relocatable class\iref{class.prop}. + +\pnum +Unless explicitly stated otherwise, it is unspecified whether a class \tcode{C} +is a replaceable class\iref{class.prop} if assigning an xvalue \tcode{a} of +type \tcode{C} to an object \tcode{b} of type \tcode{C} is semantically +equivalent to destroying \tcode{b} and then constructing from \tcode{a} in +\tcode{b}'s place. + \rSec3[protection.within.classes]{Protection within classes} \pnum @@ -3844,7 +3925,7 @@ Destructor operations defined in the \Cpp{} standard library shall not throw exceptions. Every destructor in the \Cpp{} standard library shall behave as if it had a -non-throwing exception specification. +non-throwing exception specification\iref{except.spec}. \pnum Functions defined in the @@ -3872,6 +3953,15 @@ for a non-virtual function by adding a non-throwing exception specification. +\rSec3[res.contract.assertions]{Contract assertions} + +\pnum +Unless specified otherwise, +an implementation may check +the specified preconditions and postconditions of a function +in the \Cpp{} standard library using contract +assertions\iref{basic.contract,structure.specifications}. + \rSec3[value.error.codes]{Value of error codes} \pnum @@ -3899,7 +3989,7 @@ Objects of types defined in the \Cpp{} standard library may be moved from\iref{class.copy.ctor}. Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall -be placed in a valid but unspecified state. +be placed in a valid but unspecified state\iref{defns.valid}. \pnum An object of a type defined in the \Cpp{} standard library may be diff --git a/source/limits.tex b/source/limits.tex index 60c9dc3b69..bdc1f3deb6 100644 --- a/source/limits.tex +++ b/source/limits.tex @@ -1,22 +1,11 @@ %!TEX root = std.tex -\normannex{implimits}{Implementation quantities} +\infannex{implimits}{Implementation quantities} \pnum -Because computers are finite, \Cpp{} implementations are inevitably -limited in the size of the programs they can successfully process. -Every implementation shall -document those limitations where known. -This documentation may cite fixed limits where they -exist, say how to compute variable limits as a function -of available resources, or say that fixed limits do not exist -or are unknown. - -\pnum -The limits may constrain quantities -that include those described below or others. -The bracketed number following each quantity is recommended -as the minimum for that quantity. -However, these quantities are only guidelines and do not determine compliance. +Implementations can exhibit limitations for various quantities; +some possibilities are presented in the following list. +The bracketed number following each quantity is +a potential minimum value for that quantity. \begin{itemize} \item% Nesting levels of compound statements\iref{stmt.block}, diff --git a/source/locales.tex b/source/locales.tex deleted file mode 100644 index 26ea841200..0000000000 --- a/source/locales.tex +++ /dev/null @@ -1,5366 +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 ISO 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 subclause \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 \libheader{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} & \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} & 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 \libheader{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} & \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} & \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} & 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} & \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}} - -\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}} - -\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}} - -\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 bff719918e..ec88684fcd 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -39,20 +39,18 @@ \newenvironment{addedblock}{\color{addclr}}{\color{black}} \newenvironment{removedblock}{\color{remclr}}{\color{black}} -%%-------------------------------------------------- +%%------------------------------------------------------------- %% Grammar extraction. -%%-------------------------------------------------- -\def\gramSec[#1]#2{} - +%% Assumes that the output file \gramout is managed externally. +%%------------------------------------------------------------- \makeatletter -\newcommand{\FlushAndPrintGrammar}{% -\immediate\closeout\XTR@out% -\immediate\openout\XTR@out=std-gram-dummy.tmp% -\def\gramSec[##1]##2{\rSec1[##1]{##2}}% -\input{std-gram.ext}% -} +\newcommand{\gramWrite}[1]{\protected@write\gramout{}{#1}} +\newcommand{\meaningbody}[1]{\expandafter\strip@prefix\meaning#1} \makeatother +\newcommand{\gramSec}[2][]{\gramWrite{% +\string\rSec1\string[\string#1\string]\string{\string#2\string}}} + %%-------------------------------------------------- % Escaping for index entries. Replaces ! with "! throughout its argument. %%-------------------------------------------------- @@ -147,7 +145,7 @@ % \indeximpldef synthesizes a collation key from the argument; that is, an % invocation \indeximpldef{arg} emits an index entry `key@arg`, where `key` -% is derived from `arg` by replacing the folowing list of commands with their +% is derived from `arg` by replacing the following list of commands with their % bare content. This allows, say, collating plain text and code. \newcommand{\indeximpldef}[1]{% \let\otextup\textup% @@ -214,12 +212,21 @@ \newcommand{\libmember}[2]{\indexlibrarymember{#1}{#2}#1} \newcommand{\libspec}[2]{\indexlibrarymemberx{#1}{#2}#1} +% index for macros +% \libmacro is suitable for use directly in header synopses to add the macro +% to both the text and the library index. \libxmacro does the same, but +% prepends a well-rendered double underscore. +\newcommand{\libmacro}[1]{\indexlibraryglobal{#1}\CodeStylex{#1}} +\newcommand{\libxmacro}[1]{\indexlibraryglobal{\idxxname{#1}}\CodeStylex{\xname{#1}}} + % index for library headers -\newcommand{\libheader}[1]{\indexhdr{#1}\tcode{<#1>}} +\newcommand{\libheaderx}[2]{\indexhdr{#1}\tcode{<#2>}} +\newcommand{\libheader}[1]{\libheaderx{#1}{#1}} \newcommand{\indexheader}[1]{\index[headerindex]{\idxhdr{#1}|idxbfpage}} \newcommand{\libheaderdef}[1]{\indexheader{#1}\tcode{<#1>}} \newcommand{\libnoheader}[1]{\indextext{\idxhdr{#1}!absence thereof}\tcode{<#1>}} -\newcommand{\libheaderrefx}[2]{\libheader{#1}\iref{#2}} +\newcommand{\libheaderrefxx}[3]{\libheaderx{#1}{#2}\iref{#3}} +\newcommand{\libheaderrefx}[2]{\libheaderrefxx{#1}{#1}{#2}} \newcommand{\libheaderref}[1]{\libheaderrefx{#1}{#1.syn}} \newcommand{\libdeprheaderref}[1]{\libheaderrefx{#1}{depr.#1.syn}} @@ -286,6 +293,9 @@ \newcommand{\CppXXVI}{\Cpp{} 2026} \newcommand{\IsoCUndated}{ISO/IEC 9899} \newcommand{\IsoC}{\IsoCUndated{}:2018} +\newcommand{\IsoFloatUndated}{ISO/IEC 60559} +\newcommand{\IsoPosixUndated}{ISO/IEC/IEEE 9945} +\newcommand{\IsoPosix}{\IsoPosixUndated{}:2009} \newcommand{\opt}[1]{#1\ensuremath{_\mathit{\color{black}opt}}} \newcommand{\bigoh}[1]{\ensuremath{\mathscr{O}(#1)}} @@ -318,7 +328,7 @@ \newcommand{\newnoteenvironment}[3]{ \newsubclausecounter{#1} \newenvironment{tail#1} -{\par\small\stepcounter{#1}\noteintro{#2}} +{\par\small\penalty -200\stepcounter{#1}\noteintro{#2}} {\noteoutro{#3}} \newenvironment{#1} {\begin{tail#1}} @@ -354,6 +364,7 @@ \newcommand{\constraints}{\Fundesc{Constraints}} \newcommand{\mandates}{\Fundesc{Mandates}} \newcommand{\expects}{\Fundesc{Preconditions}} +\newcommand{\hardexpects}{\Fundesc{Hardened preconditions}} \newcommand{\effects}{\Fundesc{Effects}} \newcommand{\ensures}{\Fundesc{Postconditions}} \newcommand{\returns}{\Fundesc{Returns}} @@ -364,15 +375,14 @@ \newcommand{\errors}{\Fundesc{Error conditions}} \newcommand{\sync}{\Fundesc{Synchronization}} \newcommand{\implimits}{\Fundesc{Implementation limits}} -\newcommand{\replaceable}{\Fundesc{Replaceable}} \newcommand{\result}{\Fundesc{Result}} \newcommand{\returntype}{\Fundesc{Return type}} \newcommand{\ctype}{\Fundesc{Type}} \newcommand{\templalias}{\Fundesc{Alias template}} %% Cross-reference -\newcommand{\xref}{\textsc{See also:}\space} -\newcommand{\xrefc}[1]{\xref{} \IsoC{}, #1} +\newcommand{\xref}[1]{\textsc{See also:}\space #1} +\newcommand{\xrefc}[1]{\xref{\IsoC{}, #1}} \newcommand{\termref}[3]{\textit{#2}{#3}\iref{#1}} % in Clause 3 %% Inline comma-separated parenthesized references @@ -544,6 +554,9 @@ \newcommand{\cv}{\ifmmode\mathit{cv}\else\cvqual{cv}\fi} \newcommand{\numconst}[1]{\textsl{#1}} \newcommand{\logop}[1]{\textsc{#1}} +\DeclareMathOperator{\mullo}{mullo} +\DeclareMathOperator{\mulhi}{mulhi} +\newcommand{\cedef}{\mathrel{\mathop:}=} % "colon-equals definition" %%-------------------------------------------------- %% Environments for code listings. @@ -579,22 +592,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}{} @@ -614,6 +611,17 @@ \newcommand{\atsign}{@} \makeatother +%%-------------------------------------------------- +%% Formulae +%%-------------------------------------------------- + +% usage: \begin{formula}{XREF} +\newenvironment{formula}[1] +{\begin{equation}\label{eq:#1}} +{\end{equation}} + +\renewcommand{\eqref}[1]{Formula \nolinebreak[3] \hyperref[eq:#1]{\ref*{eq:#1}}} + %%-------------------------------------------------- %% Indented text %%-------------------------------------------------- @@ -628,9 +636,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 @@ -657,7 +665,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} @@ -681,7 +699,12 @@ \nonfrenchspacing } -\newenvironment{simplebnf} +% "ncbnf" is the non-copied "base" versions of the bnf environment; +% instances of the full "bnf" environment is copied to the grammar +% extraction file. +% (Similarly for "ncsimplebnf", though in fact we never extract any +% hypothetical "simplebnf" environments.) +\newenvironment{ncsimplebnf} { \begin{bnfbase} \BnfNontermshape @@ -692,7 +715,7 @@ \end{bnfbase} } -\newenvironment{bnf} +\newenvironment{ncbnf} { \begin{bnfbase} \begin{bnflist} @@ -704,6 +727,7 @@ \end{bnfbase} } +% The regex grammar is never copied. \newenvironment{ncrebnf} { \begin{bnfbase} @@ -717,11 +741,10 @@ \end{bnfbase} } -% non-copied versions of bnf environments -\let\ncsimplebnf\simplebnf -\let\endncsimplebnf\endsimplebnf -\let\ncbnf\bnf -\let\endncbnf\endbnf +\NewEnviron{bnf}{\begin{ncbnf}% +\BODY% +\gramWrite{\string\begin{ncbnf}\meaningbody\BODY\string\end{ncbnf}}% +\end{ncbnf}}{} %%-------------------------------------------------- %% Environment for imported graphics diff --git a/source/memory.tex b/source/memory.tex index 1a80d14ed0..dfa3087c95 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -13,14 +13,15 @@ \begin{libsumtab}{Memory management library summary}{mem.summary} \ref{memory} & Memory & \tcode{}, \tcode{} \\ \rowsep -\ref{smartptr} & Smart pointers & \tcode{} \\ \rowsep -\ref{mem.res} & Memory resources & \tcode{} \\ \rowsep +\ref{smartptr} & Smart pointers & \tcode{} \\ \rowsep +\ref{mem.composite.types} & Types for composite class design & \tcode{} \\ \rowsep +\ref{mem.res} & Memory resources & \tcode{} \\ \rowsep \ref{allocator.adaptor} & Scoped allocators & \tcode{} \\ \end{libsumtab} \rSec1[memory]{Memory} -\rSec2[memory.general]{In general} +\rSec2[memory.general]{General} \pnum Subclause~\ref{memory} describes the contents of the header @@ -82,7 +83,9 @@ // \ref{ptr.align}, pointer alignment void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding template - [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding + constexpr T* assume_aligned(T* ptr); // freestanding + template + bool is_sufficiently_aligned(T* ptr); // \ref{obj.lifetime}, explicit lifetime management template @@ -102,6 +105,10 @@ template const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding size_t n) noexcept; + template + T* trivially_relocate(T* first, T* last, T* result); // freestanding + template + constexpr T* relocate(T* first, T* last, T* result); // freestanding // \ref{allocator.tag}, allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; // freestanding @@ -185,76 +192,83 @@ concept @\exposconcept{nothrow-forward-range}@ = @\seebelow@; // \expos template - void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding - NoThrowForwardIterator last); + constexpr void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding + NoThrowForwardIterator last); template - void uninitialized_default_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, + void uninitialized_default_construct(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator last); template - NoThrowForwardIterator + constexpr NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding template NoThrowForwardIterator - uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, Size n); + uninitialized_default_construct_n(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + Size n); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct(I first, S last); // freestanding + constexpr I uninitialized_default_construct(I first, S last); // freestanding template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_default_construct(R&& r); // freestanding + constexpr borrowed_iterator_t uninitialized_default_construct(R&& r); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_default_construct_n(I first, iter_difference_t n); // freestanding + constexpr I uninitialized_default_construct_n(I first, // freestanding + iter_difference_t n); } template - void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding - NoThrowForwardIterator last); + constexpr void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding + NoThrowForwardIterator last); template - void uninitialized_value_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, + void uninitialized_value_construct(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} NoThrowForwardIterator last); template - NoThrowForwardIterator + constexpr NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding template NoThrowForwardIterator - uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, Size n); + uninitialized_value_construct_n(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + Size n); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct(I first, S last); // freestanding + constexpr I uninitialized_value_construct(I first, S last); // freestanding template<@\exposconcept{nothrow-forward-range}@ R> requires @\libconcept{default_initializable}@> - borrowed_iterator_t uninitialized_value_construct(R&& r); // freestanding + constexpr borrowed_iterator_t uninitialized_value_construct(R&& r); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I> requires @\libconcept{default_initializable}@> - I uninitialized_value_construct_n(I first, iter_difference_t n); // freestanding + constexpr I uninitialized_value_construct_n(I first, // freestanding + iter_difference_t n); } template - NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding - InputIterator last, - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding + InputIterator last, + NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, + NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // freestanding-deleted, + ForwardIterator first, // see \ref{algorithms.parallel.overloads} + ForwardIterator last, NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, // freestanding - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, // freestanding + Size n, + NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, + NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // freestanding-deleted, + ForwardIterator first, // see \ref{algorithms.parallel.overloads} + Size n, NoThrowForwardIterator result); namespace ranges { @@ -263,39 +277,41 @@ template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_reference_t> - uninitialized_copy_result + constexpr uninitialized_copy_result uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_reference_t> - uninitialized_copy_result, borrowed_iterator_t> + constexpr uninitialized_copy_result, borrowed_iterator_t> uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding template using uninitialized_copy_n_result = in_out_result; // freestanding template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_reference_t> - uninitialized_copy_n_result + constexpr uninitialized_copy_n_result uninitialized_copy_n(I ifirst, iter_difference_t n, // freestanding O ofirst, S olast); } template - NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding - InputIterator last, - NoThrowForwardIterator result); + constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding + InputIterator last, + NoThrowForwardIterator result); template - NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, + NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // freestanding-deleted, + ForwardIterator first, // see \ref{algorithms.parallel.overloads} + ForwardIterator last, NoThrowForwardIterator result); template - pair + constexpr pair uninitialized_move_n(InputIterator first, Size n, // freestanding NoThrowForwardIterator result); template pair - uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, NoThrowForwardIterator result); + uninitialized_move_n(ExecutionPolicy&& exec, // freestanding-deleted, + ForwardIterator first, Size n, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator result); namespace ranges { template @@ -303,11 +319,11 @@ template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S1, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S2> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> - uninitialized_move_result + constexpr uninitialized_move_result uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> requires @\libconcept{constructible_from}@, range_rvalue_reference_t> - uninitialized_move_result, borrowed_iterator_t> + constexpr uninitialized_move_result, borrowed_iterator_t> uninitialized_move(IR&& in_range, OR&& out_range); // freestanding template @@ -315,37 +331,40 @@ template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> - uninitialized_move_n_result + constexpr uninitialized_move_n_result uninitialized_move_n(I ifirst, iter_difference_t n, // freestanding O ofirst, S olast); } template - void uninitialized_fill(NoThrowForwardIterator first, // freestanding - NoThrowForwardIterator last, const T& x); + constexpr void uninitialized_fill(NoThrowForwardIterator first, // freestanding + NoThrowForwardIterator last, const T& x); template - void uninitialized_fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, NoThrowForwardIterator last, + void uninitialized_fill(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator last, const T& x); template - NoThrowForwardIterator + constexpr NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding template NoThrowForwardIterator - uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, Size n, const T& x); + uninitialized_fill_n(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + Size n, const T& x); namespace ranges { template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill(I first, S last, const T& x); // freestanding + constexpr I uninitialized_fill(I first, S last, const T& x); // freestanding template<@\exposconcept{nothrow-forward-range}@ R, class T> requires @\libconcept{constructible_from}@, const T&> - borrowed_iterator_t uninitialized_fill(R&& r, const T& x); // freestanding + constexpr borrowed_iterator_t uninitialized_fill(R&& r, const T& x); // freestanding template<@\exposconcept{nothrow-forward-iterator}@ I, class T> requires @\libconcept{constructible_from}@, const T&> - I uninitialized_fill_n(I first, iter_difference_t n, const T& x); // freestanding + constexpr I uninitialized_fill_n(I first, // freestanding + iter_difference_t n, const T& x); } // \ref{specialized.construct}, \tcode{construct_at} @@ -364,14 +383,15 @@ constexpr void destroy(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template - void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, NoThrowForwardIterator last); + void destroy(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator last); template constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding Size n); template - NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - NoThrowForwardIterator first, Size n); + NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, Size n); // see \ref{algorithms.parallel.overloads} namespace ranges { template<@\libconcept{destructible}@ T> @@ -583,6 +603,22 @@ // \ref{inout.ptr}, function template \tcode{inout_ptr} template auto inout_ptr(Smart& s, Args&&... args); // freestanding + + // \ref{indirect}, class template \tcode{indirect} + template> + class indirect; + + // \ref{indirect.hash}, hash support + template struct hash>; + + // \ref{polymorphic}, class template \tcode{polymorphic} + template> + class polymorphic; + + namespace pmr { + template using indirect = indirect>; + template using polymorphic = polymorphic>; + } } \end{codeblock} @@ -829,7 +865,7 @@ \indexlibraryglobal{assume_aligned}% \begin{itemdecl} template - [[nodiscard]] constexpr T* assume_aligned(T* ptr); + constexpr T* assume_aligned(T* ptr); \end{itemdecl} \begin{itemdescr} @@ -839,9 +875,9 @@ \pnum \expects -\tcode{ptr} points to an object \tcode{X} of +\tcode{ptr} points to an object $X$ of a type similar\iref{conv.qual} to \tcode{T}, -where \tcode{X} has alignment \tcode{N}\iref{basic.align}. +where $X$ has alignment \tcode{N}\iref{basic.align}. \pnum \returns @@ -853,17 +889,39 @@ \pnum \begin{note} -The alignment assumption on an object \tcode{X} +The alignment assumption on an object $X$ expressed by a call to \tcode{assume_aligned} might result in generation of more efficient code. It is up to the program to ensure that the assumption actually holds. The call does not cause the implementation to verify or enforce this. An implementation might only make the assumption -for those operations on \tcode{X} that access \tcode{X} +for those operations on $X$ that access $X$ through the pointer returned by \tcode{assume_aligned}. \end{note} \end{itemdescr} +\indexlibraryglobal{is_sufficiently_aligned}% +\begin{itemdecl} +template + bool is_sufficiently_aligned(T* ptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{p} points to +an object \tcode{X} of a type similar\iref{conv.qual} to \tcode{T}. + +\pnum +\returns +\tcode{true} if \tcode{X} has alignment at least \tcode{Alignment}, +otherwise \tcode{false}. + +\pnum +\throws +Nothing. +\end{itemdescr} + \rSec2[obj.lifetime]{Explicit lifetime management} \indexlibraryglobal{start_lifetime_as}% @@ -961,6 +1019,128 @@ a pointer that compares equal to \tcode{p}\iref{expr.eq}. \end{itemdescr} +\indexlibraryglobal{trivially_relocate}% +\begin{itemdecl} +template + T* trivially_relocate(T* first, T* last, T* result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_trivially_relocatable_v \&\& !is_const_v} is \tcode{true}. +\tcode{T} is not an array of unknown bound. + +\pnum +\expects +\begin{itemize} +\item + \range{first}{last} is a valid range. +\item + \range{result}{result + (last - first)} denotes a region of storage that + is a subset of the region reachable through \tcode{result}\iref{basic.compound} + and suitably aligned for the type \tcode{T}. +\item + No element in the range \range{first}{last} is a potentially-overlapping subobject. +\end{itemize} + +\pnum +\ensures +No effect if \tcode{result == first} is \tcode{true}. +Otherwise, the range denoted by \range{result}{result + (last - first)} +contains objects (including subobjects) whose lifetime has begun and whose +object representations are the original object representations of the +corresponding objects in the source range \range{first}{last} except +for any parts of the object representations used by the implementation to +represent type information\iref{intro.object}. If any of the objects has +union type, its active member is the same as that of the corresponding object +in the source range. If any of the aforementioned objects has a non-static +data member of reference type, that reference refers to the same entity as +does the corresponding reference in the source range. The lifetimes of the +original objects in the source range have ended. + +\pnum +\returns +\tcode{result + (last - first)}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Linear in the length of the source range. + +\pnum +\remarks +The destination region of storage is considered reused\iref{basic.life}. +No constructors or destructors are invoked. + +\begin{note} +Overlapping ranges are supported. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{relocate}% +\begin{itemdecl} +template + constexpr T* relocate(T* first, T* last, T* result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_nothrow_relocatable_v \&\& !is_const_v} is \tcode{true}. +\tcode{T} is not an array of unknown bound. + +\pnum +\expects +\begin{itemize} +\item + \range{first}{last} is a valid range. +\item + \range{result}{result + (last - first)} denotes a region of storage that is + a subset of the region reachable through \tcode{result}\iref{basic.compound} + and suitably aligned for the type \tcode{T}. +\item + No element in the range \range{first}{last} is a potentially-overlapping + subobject. +\end{itemize} + +\pnum +\effects +\begin{itemize} +\item + If \tcode{result == first} is \tcode{true}, no effect; +\item + otherwise, if not called during constant evaluation and + \tcode{is_trivially_relocatable_v} is \tcode{true}, then has + effects equivalent to: \tcode{trivially_relocate(first, last, result);} +\item + otherwise, for each integer \tcode{i} in \range{0}{last - first}, + \begin{itemize} + \item + if \tcode{T} is an array type, equivalent to: + \tcode{relocate(begin(first[i]), end(first[i]), *start_lifetime_as(result + i));} + \item + otherwise, equivalent to: + \tcode{construct_at(result + i, std::move(first[i])); destroy_at(first + i);} + \end{itemize} +\end{itemize} + +\pnum +\returns +\tcode{result + (last - first)}. + +\pnum +\throws +Nothing. + +\begin{note} +Overlapping ranges are supported. +\end{note} +\end{itemdescr} + \rSec2[allocator.tag]{Allocator argument tag} \indexlibraryglobal{allocator_arg_t}% @@ -1379,10 +1559,9 @@ template using rebind_alloc = @\seebelow@; template using rebind_traits = allocator_traits>; - [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n); - [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, - const_void_pointer hint); - [[nodiscard]] static constexpr allocation_result + static constexpr pointer allocate(Alloc& a, size_type n); + static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); + static constexpr allocation_result allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); @@ -1550,7 +1729,7 @@ \indexlibrarymember{allocate}{allocator_traits}% \begin{itemdecl} -[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n); +static constexpr pointer allocate(Alloc& a, size_type n); \end{itemdecl} \begin{itemdescr} @@ -1561,7 +1740,7 @@ \indexlibrarymember{allocate}{allocator_traits}% \begin{itemdecl} -[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); +static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); \end{itemdecl} \begin{itemdescr} @@ -1572,8 +1751,7 @@ \indexlibrarymember{allocate_at_least}{allocator_traits}% \begin{itemdecl} -[[nodiscard]] static constexpr allocation_result - allocate_at_least(Alloc& a, size_type n); +static constexpr allocation_result allocate_at_least(Alloc& a, size_type n); \end{itemdecl} \begin{itemdescr} @@ -1634,7 +1812,7 @@ \pnum \returns \tcode{a.max_size()} if that expression is well-formed; otherwise, -\tcode{numeric_limits::\brk{}max()/sizeof(value_type)}. +\tcode{numeric_limits::\brk{}max() / sizeof(value_type)}. \end{itemdescr} \indexlibrarymember{select_on_container_copy_construction}{allocator_traits}% @@ -1673,7 +1851,7 @@ \begin{codeblock} namespace std { template class allocator { - public: + public: using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; @@ -1685,8 +1863,8 @@ constexpr ~allocator(); constexpr allocator& operator=(const allocator&) = default; - [[nodiscard]] constexpr T* allocate(size_t n); - [[nodiscard]] constexpr allocation_result allocate_at_least(size_t n); + constexpr T* allocate(size_t n); + constexpr allocation_result allocate_at_least(size_t n); constexpr void deallocate(T* p, size_t n); }; } @@ -1707,7 +1885,7 @@ \indexlibrarymember{allocate}{allocator}% \begin{itemdecl} -[[nodiscard]] constexpr T* allocate(size_t n); +constexpr T* allocate(size_t n); \end{itemdecl} \begin{itemdescr} @@ -1737,7 +1915,7 @@ \indexlibrarymember{allocate_at_least}{allocator}% \begin{itemdecl} -[[nodiscard]] constexpr allocation_result allocate_at_least(size_t n); +constexpr allocation_result allocate_at_least(size_t n); \end{itemdecl} \begin{itemdescr} @@ -1935,7 +2113,7 @@ \rSec3[unique.ptr.dltr]{Default deleters} -\rSec4[unique.ptr.dltr.general]{In general} +\rSec4[unique.ptr.dltr.general]{General} \pnum The class template \tcode{default_delete} serves as the default deleter (destruction policy) @@ -2086,6 +2264,14 @@ } \end{codeblock} +\pnum +A program that instantiates the definition of \tcode{unique_ptr} +is ill-formed if \tcode{T*} is an invalid type. +\begin{note} +This prevents the instantiation of specializations such as +\tcode{unique_ptr} and \tcode{unique_ptr}. +\end{note} + \pnum The default type for the template parameter \tcode{D} is \tcode{default_delete}. A client-supplied template argument @@ -2436,9 +2622,13 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{reference_converts_from_temporary_v, decltype(\linebreak{}*declval())>} is \tcode{false}. + \pnum \expects -\tcode{get() != nullptr}. +\tcode{get() != nullptr} is \tcode{true}. \pnum \returns @@ -3275,7 +3465,7 @@ reflect modifications that can introduce data races. \pnum -For the purposes of subclause \ref{smartptr}, +For the purposes of \ref{smartptr}, a pointer type \tcode{Y*} is said to be \defnx{compatible with}{compatible with!\idxcode{shared_ptr}} a pointer type \tcode{T*} when either @@ -3293,10 +3483,10 @@ then \tcode{remove_cv_t*} shall be implicitly convertible to \tcode{T*} and the constructor evaluates the statement: \begin{codeblock} -if (p != nullptr && p->weak_this.expired()) - p->weak_this = shared_ptr>(*this, const_cast*>(p)); +if (p != nullptr && p->@\exposid{weak-this}@.expired()) + p->@\exposid{weak-this}@ = shared_ptr>(*this, const_cast*>(p)); \end{codeblock} -The assignment to the \tcode{weak_this} member is not atomic and +The assignment to the \exposid{weak-this} member is not atomic and conflicts with any potentially concurrent access to the same object\iref{intro.multithread}. \indexlibraryctor{shared_ptr}% @@ -3972,15 +4162,15 @@ \tcode{allocate_shared} shall initialize this (sub)object via the expression \begin{itemize} - \item \tcode{allocator_traits::construct(a2, pv, v)} or - \item \tcode{allocator_traits::construct(a2, pv, l...)} + \item \tcode{allocator_traits::construct(a2, pu, v)} or + \item \tcode{allocator_traits::construct(a2, pu, l...)} \end{itemize} respectively, - where \tcode{pv} points to storage - suitable to hold an object of type \tcode{U} and - \tcode{a2} of type \tcode{A2} is a rebound copy of - the allocator \tcode{a} passed to \tcode{allocate_shared} - such that its \tcode{value_type} is \tcode{remove_cv_t}. + where \tcode{pu} is a pointer of type \tcode{remove_cv_t*} + pointing to storage + suitable to hold an object of type \tcode{remove_cv_t} and + \tcode{a2} of type \tcode{A2} is a potentially rebound copy of + the allocator \tcode{a} passed to \tcode{allocate_shared}. \item When a (sub)object of non-array type \tcode{U} is specified to have a default initial value, @@ -3991,13 +4181,13 @@ \item When a (sub)object of non-array type \tcode{U} is specified to have a default initial value, - \tcode{allocate_shared} shall initialize this (sub)object - via the expression \tcode{allocator_traits::construct(a2, pv)}, - where \tcode{pv} points to storage - suitable to hold an object of type \tcode{U} and - \tcode{a2} of type \tcode{A2} is a rebound copy of - the allocator \tcode{a} passed to \tcode{allocate_shared} - such that its \tcode{value_type} is \tcode{remove_cv_t}. + \tcode{allocate_shared} initializes this (sub)object + via the expression \tcode{allocator_traits::construct(a2, pu)}, + where \tcode{pu} is a pointer of type \tcode{remove_cv_t*} + pointing to storage + suitable to hold an object of type \tcode{remove_cv_t} and + \tcode{a2} of type \tcode{A2} is a potentially rebound copy of + the allocator \tcode{a} passed to \tcode{allocate_shared}. \item When a (sub)object of non-array type \tcode{U} is initialized by \tcode{make_shared_for_overwrite} or\linebreak % avoid Overfull @@ -4014,18 +4204,20 @@ of their original construction. \item When a (sub)object of non-array type \tcode{U} - that was initialized by \tcode{make_shared} is to be destroyed, - it is destroyed via the expression \tcode{pv->\~{}U()} where - \tcode{pv} points to that object of type \tcode{U}. + that was initialized by \tcode{make_shared}, + \tcode{make_shared_for_overwrite}, or \tcode{allocate_shared_for_overwrite} + is to be destroyed, + it is destroyed via the expression \tcode{pu->\~{}U()} where + \tcode{pu} points to that object of type \tcode{U}. \item When a (sub)object of non-array type \tcode{U} that was initialized by \tcode{allocate_shared} is to be destroyed, it is destroyed via the expression - \tcode{allocator_traits::destroy(a2, pv)} where - \tcode{pv} points to that object of type \tcode{remove_cv_t} and - \tcode{a2} of type \tcode{A2} is a rebound copy of - the allocator \tcode{a} passed to \tcode{allocate_shared} - such that its \tcode{value_type} is \tcode{remove_cv_t}. + \tcode{allocator_traits::destroy(a2, pu)} where + \tcode{pu} is a pointer of type \tcode{remove_cv_t*} + pointing to that object of type \tcode{remove_cv_t} and + \tcode{a2} of type \tcode{A2} is a potentially rebound copy of + the allocator \tcode{a} passed to \tcode{allocate_shared}. \end{itemize} \begin{note} These functions will typically allocate more memory than \tcode{sizeof(T)} to @@ -4356,7 +4548,7 @@ \begin{note} The seemingly equivalent expression \tcode{shared_ptr(static_cast(r.get()))} -will eventually result in undefined behavior, attempting to delete the +can result in undefined behavior, attempting to delete the same object twice. \end{note} \end{itemdescr} @@ -4393,7 +4585,7 @@ \pnum \begin{note} The seemingly equivalent expression -\tcode{shared_ptr(dynamic_cast(r.get()))} will eventually result in +\tcode{shared_ptr(dynamic_cast(r.get()))} can result in undefined behavior, attempting to delete the same object twice. \end{note} \end{itemdescr} @@ -4422,7 +4614,7 @@ \pnum \begin{note} The seemingly equivalent expression -\tcode{shared_ptr(const_cast(r.get()))} will eventually result in +\tcode{shared_ptr(const_cast(r.get()))} can result in undefined behavior, attempting to delete the same object twice. \end{note} \end{itemdescr} @@ -4451,7 +4643,7 @@ \pnum \begin{note} The seemingly equivalent expression -\tcode{shared_ptr(reinterpret_cast(r.get()))} will eventually result in +\tcode{shared_ptr(reinterpret_cast(r.get()))} can result in undefined behavior, attempting to delete the same object twice. \end{note} \end{itemdescr} @@ -4988,7 +5180,7 @@ weak_ptr weak_from_this() const noexcept; private: - mutable weak_ptr weak_this; // \expos + mutable weak_ptr @\exposid{weak-this}@; // \expos }; } \end{codeblock} @@ -5006,7 +5198,7 @@ \begin{itemdescr} \pnum \effects -Value-initializes \tcode{weak_this}. +Value-initializes \exposid{weak-this}. \end{itemdescr} \indexlibrarymember{operator=}{enable_shared_from_this}% @@ -5021,7 +5213,7 @@ \pnum \begin{note} -\tcode{weak_this} is not changed. +\exposid{weak-this} is not changed. \end{note} \end{itemdescr} @@ -5035,7 +5227,7 @@ \begin{itemdescr} \pnum \returns -\tcode{shared_ptr(weak_this)}. +\tcode{shared_ptr(\exposid{weak-this})}. \end{itemdescr} \indexlibraryglobal{weak_ptr}% @@ -5048,7 +5240,7 @@ \begin{itemdescr} \pnum \returns -\tcode{weak_this}. +\exposid{weak-this}. \end{itemdescr} \rSec2[util.smartptr.hash]{Smart pointer hash support} @@ -5178,6 +5370,8 @@ Then, equivalent to: \begin{itemize} \item +% pretend to \item that there is real text here, but undo the vertical spacing +\mbox{}\vspace{-\baselineskip}\vspace{-\parskip} \begin{codeblock} s.reset(); \end{codeblock} @@ -5556,6 +5750,1558 @@ \tcode{inout_ptr_t(s, std::forward(args)...)}. \end{itemdescr} +\rSec1[mem.composite.types]{Types for composite class design} + +\rSec2[indirect]{Class template \tcode{indirect}} + +\rSec3[indirect.general]{General} + +\pnum +An indirect object manages the lifetime of an owned object. +An indirect object is +\defnx{valueless}{valueless!indirect object} if it has no owned object. +An indirect object may become valueless only after it has been moved from. + +\pnum +In every specialization \tcode{indirect}, +if the type \tcode{allocator_traits::value_type} +is not the same type as \tcode{T}, +the program is ill-formed. +Every object of type \tcode{indirect} +uses an object of type \tcode{Allocator} to allocate and free storage +for the owned object as needed. + +\pnum +Constructing an owned object with \tcode{args...} +using the allocator \tcode{a} means calling +\tcode{allocator_traits::construct(a, \exposid{p}, args...)} where +\tcode{args} is an expression pack, +\tcode{a} is an allocator, and +\exposid{p} is a pointer obtained by +calling \tcode{allocator_traits::allocate}. + +\pnum +The member \exposid{alloc} is used for +any memory allocation and element construction +performed by member functions +during the lifetime of each indirect object. +The allocator \exposid{alloc} may be replaced +only via assignment or \tcode{swap()}. +\tcode{Allocator} replacement is performed by +copy assignment, +move assignment, or +swapping of the allocator +only if\iref{container.reqmts}: +\begin{itemize} +\item +\tcode{allocator_traits::propagate_on_container_copy_assignment::value}, or +\item +\tcode{allocator_traits::propagate_on_container_move_assignment::value}, or +\item +\tcode{allocator_traits::propagate_on_container_swap::value} +\end{itemize} +is \tcode{true} within the implementation of +the corresponding \tcode{indirect} operation. + +\pnum +A program that instantiates the definition of +the template \tcode{indirect} with +a type for the \tcode{T} parameter that is +a non-object type, +an array type, +\tcode{in_place_t}, +a specialization of \tcode{in_place_type_t}, or +a cv-qualified type +is ill-formed. + +\pnum +The template parameter \tcode{T} of \tcode{indirect} +may be an incomplete type. + +\pnum +The template parameter \tcode{Allocator} of \tcode{indirect} +shall meet the \oldconcept{Allocator} requirements. + +\pnum +If a program declares an explicit or partial specialization of \tcode{indirect}, +the behavior is undefined. + +\rSec3[indirect.syn]{Synopsis} + +\indexlibraryglobal{indirect}% +\begin{codeblock} +namespace std { + template> + class indirect { + public: + using value_type = T; + using allocator_type = Allocator; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + + // \ref{indirect.ctor}, constructors + constexpr explicit indirect(); + constexpr explicit indirect(allocator_arg_t, const Allocator& a); + constexpr indirect(const indirect& other); + constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other); + constexpr indirect(indirect&& other) noexcept; + constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other) + noexcept(@\seebelow@); + template + constexpr explicit indirect(U&& u); + template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u); + template + constexpr explicit indirect(in_place_t, Us&&... us); + template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, + in_place_t, Us&&... us); + template + constexpr explicit indirect(in_place_t, initializer_list ilist, Us&&... us); + template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, + in_place_t, initializer_list ilist, Us&&... us); + + // \ref{indirect.dtor}, destructor + constexpr ~indirect(); + + // \ref{indirect.asgn}, assignment + constexpr indirect& operator=(const indirect& other); + constexpr indirect& operator=(indirect&& other) noexcept(@\seebelow@); + template + constexpr indirect& operator=(U&& u); + + // \ref{indirect.obs}, observers + constexpr const T& operator*() const & noexcept; + constexpr T& operator*() & noexcept; + constexpr const T&& operator*() const && noexcept; + constexpr T&& operator*() && noexcept; + constexpr const_pointer operator->() const noexcept; + constexpr pointer operator->() noexcept; + constexpr bool valueless_after_move() const noexcept; + constexpr allocator_type get_allocator() const noexcept; + + // \ref{indirect.swap}, swap + constexpr void swap(indirect& other) noexcept(@\seebelow@); + friend constexpr void swap(indirect& lhs, indirect& rhs) noexcept(@\seebelow@); + + // \ref{indirect.relops}, relational operators + template + friend constexpr bool operator==(const indirect& lhs, const indirect& rhs) + noexcept(@\seebelow@); + template + friend constexpr auto operator<=>(const indirect& lhs, const indirect& rhs) + -> @\exposid{synth-three-way-result}@; + + // \ref{indirect.comp.with.t}, comparison with \tcode{T} + template + friend constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(@\seebelow@); + template + friend constexpr auto operator<=>(const indirect& lhs, const U& rhs) + -> @\exposid{synth-three-way-result}@; + + private: + pointer @\exposid{p}@; // \expos + Allocator @\exposid{alloc}@ = Allocator(); // \expos + }; + template + indirect(Value) -> indirect; + template + indirect(allocator_arg_t, Allocator, Value) + -> indirect::template rebind_alloc>; +} +\end{codeblock} + +\rSec3[indirect.ctor]{Constructors} + +\pnum +The following element applies to all functions in~\ref{indirect.ctor}: + +\begin{itemdescr} +\pnum +\throws +Nothing unless \tcode{allocator_traits::allocate} or +\tcode{allocator_traits::construct} throws. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr explicit indirect(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_default_constructible_v} is \tcode{true}. + +\pnum +\mandates +\tcode{is_default_constructible_v} is \tcode{true}. + +\pnum +\effects +Constructs an owned object of type \tcode{T} with an empty argument list, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr explicit indirect(allocator_arg_t, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_default_constructible_v} is \tcode{true}. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{T} with an empty argument list, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr indirect(const indirect& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_copy_constructible_v} is \tcode{true}. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with +\tcode{allocator_traits::select_on_contai\-ner_copy_construction(other.\exposid{alloc})}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +constructs an owned object of type \tcode{T} with \tcode{*other}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_copy_constructible_v} is \tcode{true}. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +constructs an owned object of type \tcode{T} with \tcode{*other}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr indirect(indirect&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized from +\tcode{std::move(other.\exposid{alloc})}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise \tcode{*this} takes ownership of the owned object of \tcode{other}. + +\pnum +\ensures +\tcode{other} is valueless. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other) + noexcept(allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +If \tcode{allocator_traits::is_always_equal::value} is \tcode{false} +then \tcode{T} is a complete type. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +constructs an object of type \tcode{indirect} that +takes ownership of the owned object of \tcode{other}. +Otherwise, +constructs an owned object of type \tcode{T} with \tcode{*std::move(other)}, +using the allocator \exposid{alloc}. + +\pnum +\ensures +\tcode{other} is valueless. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(U&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, indirect>} is \tcode{false}, +\item +\tcode{is_same_v, in_place_t>} is \tcode{false}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{T} with \tcode{std::forward(u)}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, indirect>} is \tcode{false}, +\item +\tcode{is_same_v, in_place_t>} is \tcode{false}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{T} with +\tcode{std::forward(u)}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(in_place_t, Us&&... us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{T} with +\tcode{std::forward(us)...}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, + in_place_t, Us&& ...us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{T} with +\tcode{std::forward(us)...}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(in_place_t, initializer_list ilist, Us&&... us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v\&, Us...>} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{T} with the arguments +\tcode{ilist, std::forward(us)...}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +template + constexpr explicit indirect(allocator_arg_t, const Allocator& a, + in_place_t, initializer_list ilist, Us&&... us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v\&, Us...>} is \tcode{true}. + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{T} with the arguments +\tcode{ilist, std::forward(us)...}, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\rSec3[indirect.dtor]{Destructor} + +\indexlibrarydtor{indirect}% +\begin{itemdecl} +constexpr ~indirect(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + +\pnum +\effects +If \tcode{*this} is not valueless, +destroys the owned object +using \tcode{allocator_traits::de\-stroy} and +then the storage is deallocated. +\end{itemdescr} + +\rSec3[indirect.asgn]{Assignment} + +\indexlibrarymember{operator=}{indirect}% +\begin{itemdecl} +constexpr indirect& operator=(const indirect& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates + +\begin{itemize} +\item +\tcode{is_copy_assignable_v} is \tcode{true}, and +\item +\tcode{is_copy_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +If \tcode{addressof(other) == this} is \tcode{true}, there are no effects. +Otherwise: + +\begin{itemize} +\item +%FIXME: We're defining what it means for an allocator to "need updating" here? +%FIXME: (Note: that this concept is used elsewhere so it must be defined)... +%FIXME: How is this an "effect"? +The allocator needs updating if +\tcode{allocator_traits::propagate_on_container_copy_assignment::value} +is \tcode{true}. + +\item +If \tcode{other} is valueless, +\tcode{*this} becomes valueless and +the owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::destroy} and +then the storage is deallocated. + +\item +Otherwise, +if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true} and +\tcode{*this} is not valueless, +equivalent to \tcode{**this = *other}. + +\item +Otherwise a new owned object is constructed in \tcode{*this} +using \tcode{allocator_traits::con\linebreak{}struct} with +the owned object from \tcode{other} as the argument, +using either the allocator in \tcode{*this} or +%FIXME: Concept "allocator needs updating" not defined/referenced. +%FIXME: Same for all usages below. +the allocator in \tcode{other} if the allocator needs updating. + +\item +The previously owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::\linebreak{}destroy} and +then the storage is deallocated. + +\item +If the allocator needs updating, +the allocator in \tcode{*this} is replaced with +a copy of the allocator in \tcode{other}. +\end{itemize} + +\pnum +\returns +A reference to \tcode{*this}. + +\pnum +\remarks +If any exception is thrown, +the result of the expression \tcode{this->valueless_after_move()} +remains unchanged. +If an exception is thrown during +the call to \tcode{T}{'s} selected copy constructor, no effect. +If an exception is thrown during the call to \tcode{T}{'s} copy assignment, +the state of its contained value +is as defined by the exception safety guarantee of +\tcode{T}{'s} copy assignment. +\end{itemdescr} + +\indexlibrarymember{operator=}{indirect}% +\begin{itemdecl} +constexpr indirect& operator=(indirect&& other) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_copy_constructible_t} is \tcode{true}. + +\pnum +\effects +If \tcode{addressof(other) == this} is \tcode{true}, there are no effects. +Otherwise: + +\begin{itemize} +\item +%FIXME: We're defining "allocator needs updating" as an effect? +%FIXME: (Same issue as above) +The allocator needs updating if +\tcode{allocator_traits::propagate_on_container_move_assignment::value} +is \tcode{true}. + +\item +If \tcode{other} is valueless, +\tcode{*this} becomes valueless and +the owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::destroy} and +then the storage is deallocated. + +\item +Otherwise, +if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +swaps the owned objects in \tcode{*this} and \tcode{other}; +the owned object in \tcode{other}, if any, +is then destroyed using \tcode{allocator_traits::destroy} and +then the storage is deallocated. + +\item +Otherwise, +constructs a new owned object with +%FIXME: "as the argument as an rvalue" is awkward. +the owned object of \tcode{other} as the argument as an rvalue, +using either +the allocator in \tcode{*this} or +the allocator in \tcode{other} +if the allocator needs updating. + +\item +The previously owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::\linebreak{}destroy} and +then the storage is deallocated. + +\item +If the allocator needs updating, +the allocator in \tcode{*this} is replaced with +a copy of the allocator in \tcode{other}. +\end{itemize} + +\pnum +\ensures +\tcode{other} is valueless. + +\pnum +\returns +A reference to \tcode{*this}. + +\pnum +\remarks +If any exception is thrown, +there are no effects on \tcode{*this} or \tcode{other}. +\end{itemdescr} + +\indexlibrarymember{operator=}{indirect}% +\begin{itemdecl} +template + constexpr indirect& operator=(U&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, indirect>} is \tcode{false}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_assignable_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +If \tcode{*this} is valueless then +constructs an owned object of type \tcode{T} with \tcode{std::forward(u)} +using the allocator \exposid{alloc}. +Otherwise, +equivalent to \tcode{**this = std::forward(u)}. + +\pnum +\returns +A reference to \tcode{*this}. +\end{itemdescr} + +\rSec3[indirect.obs]{Observers} + +\indexlibrarymember{operator*}{indirect}% +\begin{itemdecl} +constexpr const T& operator*() const & noexcept; +constexpr T& operator*() & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{*this} is not valueless. + +\pnum +\returns +\tcode{*\exposid{p}}. +\end{itemdescr} + +\indexlibrarymember{operator*}{indirect}% +\begin{itemdecl} +constexpr const T&& operator*() const && noexcept; +constexpr T&& operator*() && noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{*this} is not valueless. + +\pnum +\returns +\tcode{std::move(*\exposid{p})}. +\end{itemdescr} + +\indexlibrarymember{operator->}{indirect}% +\begin{itemdecl} +constexpr const_pointer operator->() const noexcept; +constexpr pointer operator->() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{*this} is not valueless. + +\pnum +\returns +\exposid{p}. +\end{itemdescr} + +\indexlibrarymember{valueless_after_move}{indirect}% +\begin{itemdecl} +constexpr bool valueless_after_move() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{*this} is valueless, otherwise \tcode{false}. +\end{itemdescr} + +\indexlibrarymember{get_allocator}{indirect}% +\begin{itemdecl} +constexpr allocator_type get_allocator() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{alloc}. +\end{itemdescr} + +\rSec3[indirect.swap]{Swap} + +\indexlibrarymember{swap}{indirect}% +\begin{itemdecl} +constexpr void swap(indirect& other) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If +\tcode{allocator_traits::propagate_on_container_swap::value} +is \tcode{true}, then +\tcode{Allocator} meets the \oldconcept{Swappable} requirements. +Otherwise \tcode{get_allocator() == other.\linebreak{}get_allocator()} is \tcode{true}. + +\pnum +\effects +Swaps the states of \tcode{*this} and \tcode{other}, +exchanging owned objects or valueless states. +If \tcode{allocator_traits::propagate_on_container_swap::value} +is \tcode{true}, +then the allocators of \tcode{*this} and \tcode{other} +are exchanged by calling \tcode{swap} as described in~\ref{swappable.requirements}. +Otherwise, +the allocators are not swapped. +\begin{note} +Does not call \tcode{swap} on the owned objects directly. +\end{note} +\end{itemdescr} + +\indexlibrarymember{swap}{indirect}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +constexpr void swap(indirect& lhs, indirect& rhs) noexcept(noexcept(lhs.swap(rhs))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{lhs.swap(rhs)}. +\end{itemdescr} + +\rSec3[indirect.relops]{Relational operators} + +\indexlibrarymember{operator==}{indirect}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +template + constexpr bool operator==(const indirect& lhs, const indirect& rhs) + noexcept(noexcept(*lhs == *rhs)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The expression \tcode{*lhs == *rhs} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +If \tcode{lhs} is valueless or \tcode{rhs} is valueless, +\tcode{lhs.valueless_after_move() == rhs.valueless_after_move()}; +otherwise \tcode{*lhs == *rhs}. +\end{itemdescr} + +\indexlibrarymember{\exposid{synth-three-way-result}}{indirect}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const indirect& lhs, const indirect& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{lhs} is valueless or \tcode{rhs} is valueless, +\tcode{!lhs.valueless_after_move() <=> !rhs.value\-less_after_move()}; +otherwise +\tcode{\exposid{synth-three-way}(*lhs, *rhs)}. +\end{itemdescr} + +\rSec3[indirect.comp.with.t]{Comparison with \tcode{T}} + +\indexlibrarymember{operator==}{indirect}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +template + constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(noexcept(*lhs == rhs)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The expression \tcode{*lhs == rhs} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +If \tcode{lhs} is valueless, \tcode{false}; +otherwise \tcode{*lhs == rhs}. +\end{itemdescr} + +\indexlibrarymember{\exposid{synth-three-way-result}}{indirect}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const indirect& lhs, const U& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{lhs} is valueless, \tcode{strong_ordering::less}; +otherwise \tcode{\exposid{synth-three-way}(*lhs, rhs)}. +\end{itemdescr} + +\rSec3[indirect.hash]{Hash support} + +\indexlibrarymember{hash}{indirect}% +\begin{itemdecl} +template +struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The specialization \tcode{hash>} +is enabled\iref{unord.hash} if and only if \tcode{hash} is enabled. +When enabled for an object \tcode{i} of type \tcode{indirect}, +%FIXME: Cleanup wording/punctuation and make consistent. +\tcode{hash>()(i)} evaluates to +either the same value as \tcode{hash()(*i)}, +if \tcode{i} is not valueless; +otherwise to an +\impldef{result of evaluating \tcode{hash>()(i)} if \tcode{i} is valueless} +value. +The member functions are not guaranteed to be \tcode{noexcept}. +\end{itemdescr} + +\rSec2[polymorphic]{Class template \tcode{polymorphic}} + +\rSec3[polymorphic.general]{General} + +\pnum +A polymorphic object manages the lifetime of an owned object. +A polymorphic object may own objects of +different types at different points in its lifetime. +A polymorphic object is +\defnx{valueless}{valueless!polymorphic object} +if it has no owned object. +A polymorphic object may become valueless only after it has been moved from. + +\pnum +In every specialization \tcode{polymorphic}, +if the type \tcode{allocator_traits::value_type} +is not the same type as \tcode{T}, the program is ill-formed. +Every object of type \tcode{polymorphic} +uses an object of type \tcode{Allocator} to +allocate and free storage for the owned object as needed. + +\pnum +Constructing an owned object of type \tcode{U} with \tcode{args...} +using the allocator \tcode{a} means calling +\tcode{allocator_traits::construct(a, \exposid{p}, args...)} where +\tcode{args} is an expression pack, +\tcode{a} is an allocator, and +\exposid{p} points to storage suitable for an owned object of type \tcode{U}. + +\pnum +The member \exposid{alloc} is used for +any memory allocation and element construction +performed by member functions +during the lifetime of each polymorphic value object, or +until the allocator is replaced. +The allocator may be replaced only via +assignment or \tcode{swap()}. +\tcode{Allocator} replacement is performed by +copy assignment, +move assignment, or +swapping of the allocator +only if\iref{container.reqmts}: +\begin{itemize} +\item +\tcode{allocator_traits::propagate_on_container_copy_assignment::value}, or +\item +\tcode{allocator_traits::propagate_on_container_move_assignment::value}, or +\item +\tcode{allocator_traits::propagate_on_container_swap::value} +\end{itemize} +is \tcode{true} within the implementation of +the corresponding \tcode{polymorphic} operation. + +\pnum +A program that instantiates the definition of \tcode{polymorphic} for +a non-object type, +an array type, +\tcode{in_place_t}, +a specialization of \tcode{in_place_type_t}, or +a cv-qualified type +is ill-formed. + +\pnum +The template parameter \tcode{T} of \tcode{polymorphic} +may be an incomplete type. + +\pnum +The template parameter \tcode{Allocator} of \tcode{polymorphic} +shall meet the requirements of \oldconcept{Allocator}. + +\pnum +If a program declares an explicit or +partial specialization of \tcode{polymorphic}, +the behavior is undefined. + +\rSec3[polymorphic.syn]{Synopsis} + +\indexlibraryglobal{polymorphic}% +\begin{codeblock} +namespace std { + template> + class polymorphic { + public: + using value_type = T; + using allocator_type = Allocator; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + + // \ref{polymorphic.ctor}, constructors + constexpr explicit polymorphic(); + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a); + constexpr polymorphic(const polymorphic& other); + constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other); + constexpr polymorphic(polymorphic&& other) noexcept; + constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other) + noexcept(@\seebelow@); + template + constexpr explicit polymorphic(U&& u); + template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u); + template + constexpr explicit polymorphic(in_place_type_t, Ts&&... ts); + template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, + in_place_type_t, Ts&&... ts); + template + constexpr explicit polymorphic(in_place_type_t, initializer_list ilist, Us&&... us); + template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, + in_place_type_t, initializer_list ilist, Us&&... us); + + // \ref{polymorphic.dtor}, destructor + constexpr ~polymorphic(); + + // \ref{polymorphic.asgn}, assignment + constexpr polymorphic& operator=(const polymorphic& other); + constexpr polymorphic& operator=(polymorphic&& other) noexcept(@\seebelow@); + + // \ref{polymorphic.obs}, observers + constexpr const T& operator*() const noexcept; + constexpr T& operator*() noexcept; + constexpr const_pointer operator->() const noexcept; + constexpr pointer operator->() noexcept; + constexpr bool valueless_after_move() const noexcept; + constexpr allocator_type get_allocator() const noexcept; + + // \ref{polymorphic.swap}, swap + constexpr void swap(polymorphic& other) noexcept(@\seebelow@); + friend constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(@\seebelow@); + + private: + Allocator @\exposid{alloc}@ = Allocator(); // \expos + }; +} +\end{codeblock} + +\rSec3[polymorphic.ctor]{Constructors} + +\pnum +The following element applies to all functions in~\ref{polymorphic.ctor}: + +\begin{itemdescr} +\pnum +\throws +Nothing unless \tcode{allocator_traits::allocate} or +\tcode{allocator_traits::construct} throws. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +constexpr explicit polymorphic(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_default_constructible_v} is \tcode{true}. + +\pnum +\mandates +\begin{itemize} +\item +\tcode{is_default_constructible_v} is \tcode{true}, and +\item +\tcode{is_copy_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{T} with an empty argument list +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{indirect}% +\begin{itemdecl} +constexpr explicit polymorphic(allocator_arg_t, const Allocator& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\begin{itemize} +\item +\tcode{is_default_constructible_v} is \tcode{true}, and +\item +\tcode{is_copy_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{T} with an empty argument list +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +constexpr polymorphic(const polymorphic& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with +\tcode{allocator_traits::select_on_contai\-ner_copy_construction(other.\exposid{alloc})}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +constructs an owned object of type \tcode{U}, where +\tcode{U} is the type of the owned object in \tcode{other}, with +the owned object in \tcode{other} using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +constructs an owned object of type \tcode{U}, where +\tcode{U} is the type of the owned object in \tcode{other}, with +the owned object in \tcode{other} using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +constexpr polymorphic(polymorphic&& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with +\tcode{std::move(other.\exposid{alloc})}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +either \tcode{*this} +takes ownership of the owned object of \tcode{other} or, +%FIXME: Cleanup awkward wording. +owns an object of the same type +constructed from the owned object of \tcode{other} +considering that owned object as an rvalue, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other) + noexcept(allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +If \tcode{other} is valueless, \tcode{*this} is valueless. +Otherwise, +if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +either constructs an object of type \tcode{polymorphic} that +owns the owned object of \tcode{other}, +making \tcode{other} valueless; or, +%FIXME: Cleanup awkward wording. (And similar wording elsewhere). +owns an object of the same type constructed from +the owned object of \tcode{other} +considering that owned object as an rvalue. +Otherwise, +if \tcode{\exposid{alloc} != other.\exposid{alloc}} is \tcode{true}, +constructs an object of type \tcode{polymorphic}, +considering the owned object in \tcode{other} as an rvalue, +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(U&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Where \tcode{UU} is \tcode{remove_cvref_t}, +\begin{itemize} +\item +\tcode{is_same_v} is \tcode{false}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, +\item +\tcode{is_copy_constructible_v} is \tcode{true}, +\item +\tcode{UU} is not a specialization of \tcode{in_place_type_t}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{U} with \tcode{std::forward(u)} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Where \tcode{UU} is \tcode{remove_cvref_t}, +\begin{itemize} +\item +\tcode{is_same_v} is \tcode{false}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, +\item +\tcode{is_copy_constructible_v} is \tcode{true}, and +\item +\tcode{UU} is not a specialization of \tcode{in_place_type_t}. +\end{itemize} + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{U} with \tcode{std::forward(u)} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(in_place_type_t, Ts&&... ts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, U>} is \tcode{true}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, +\item +\tcode{is_copy_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{U} with +\tcode{std::forward(ts)...} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, + in_place_type_t, Ts&&... ts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, U>} is \tcode{true}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_copy_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{U} with +\tcode{std::forward(ts)...} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(in_place_type_t, initializer_list ilist, Us&&... us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_same_v, U>} is \tcode{true}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v\&, Us...>} is \tcode{true}, +\item +\tcode{is_copy_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Constructs an owned object of type \tcode{U} with +the arguments \tcode{ilist, std::forward(us)...} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\indexlibraryctor{polymorphic}% +\begin{itemdecl} +template + constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, + in_place_type_t, initializer_list ilist, Us&&... us); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints + +\begin{itemize} +\item +\tcode{is_same_v, U>} is \tcode{true}, +\item +\tcode{derived_from} is \tcode{true}, +\item +\tcode{is_constructible_v\&, Us...>} is \tcode{true}, and +\item +\tcode{is_copy_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +\exposid{alloc} is direct-non-list-initialized with \tcode{a}. +Constructs an owned object of type \tcode{U} with the arguments +\tcode{ilist, std::forward(us)...} +using the allocator \exposid{alloc}. +\end{itemdescr} + +\rSec3[polymorphic.dtor]{Destructor} + +\indexlibrarydtor{polymorphic}% +\begin{itemdecl} +constexpr ~polymorphic(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + +\pnum +\effects +If \tcode{*this} is not valueless, +destroys the owned object using \tcode{allocator_traits::de\-stroy} and +then the storage is deallocated. +\end{itemdescr} + +\rSec3[polymorphic.asgn]{Assignment} + +\indexlibrarymember{operator=}{polymorphic}% +\indexlibrarydtor{polymorphic}% +\begin{itemdecl} +constexpr polymorphic& operator=(const polymorphic& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + +\pnum +\effects +If \tcode{addressof(other) == this} is \tcode{true}, there are no effects. +Otherwise: + +\begin{itemize} +\item +%FIXME: We're defining "allocator needs updating" as an effect? +%FIXME: (Same issue as above) +The allocator needs updating if +\tcode{allocator_traits::propagate_on_contai\-ner_copy_assignment::value} +is \tcode{true}. + +\item +If \tcode{other} is not valueless, +a new owned object is constructed in \tcode{*this} using +\tcode{allocator_traits::construct} with +the owned object from \tcode{other} as the argument, using either +the allocator in \tcode{*this} or +the allocator in \tcode{other} if the allocator needs updating. + +\item +The previously owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::\linebreak{}destroy} and +then the storage is deallocated. + +\item +If the allocator needs updating, +the allocator in \tcode{*this} is replaced with +a copy of the allocator in \tcode{other}. +\end{itemize} + +\pnum +\returns +A reference to \tcode{*this}. + +\pnum +\remarks +If any exception is thrown, there are no effects on \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{polymorphic}% +\begin{itemdecl} +constexpr polymorphic& operator=(polymorphic&& other) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +If \tcode{allocator_traits::is_always_equal::value} is \tcode{false}, +\tcode{T} is a complete type. + +\pnum +\effects +If \tcode{addressof(other) == this} is \tcode{true}, there are no effects. +Otherwise: + +\begin{itemize} +\item +%FIXME: We're defining "allocator needs updating" as an effect? +%FIXME: (Same issue as above) +The allocator needs updating if +\tcode{allocator_traits::propagate_on_container_move_assignment::value} +is \tcode{true}. + +\item +If \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +swaps the owned objects in \tcode{*this} and \tcode{other}; +the owned object in \tcode{other}, if any, +is then destroyed using \tcode{allocator_traits::destroy} and +then the storage is deallocated. + +\item +Otherwise, +if \tcode{\exposid{alloc} != other.\exposid{alloc}} is \tcode{true}; +if \tcode{other} is not valueless, +a new owned object is constructed in \tcode{*this} +using \tcode{allocator_traits::construct} with +%FIXME: Cleanup wording. +the owned object from \tcode{other} as the argument as an rvalue, +using either the allocator in \tcode{*this} or +the allocator in \tcode{other} if the allocator needs updating. + +\item +The previously owned object in \tcode{*this}, if any, +is destroyed using \tcode{allocator_traits::\linebreak{}destroy} and +then the storage is deallocated. + +\item +If the allocator needs updating, +the allocator in \tcode{*this} is replaced with +a copy of the allocator in \tcode{other}. +\end{itemize} + +\pnum +\returns +A reference to \tcode{*this}. + +\pnum +\remarks +If any exception is thrown, +there are no effects on \tcode{*this} or \tcode{other}. +\end{itemdescr} + +\rSec3[polymorphic.obs]{Observers} + +\indexlibrarymember{operator*}{polymorphic}% +\begin{itemdecl} +constexpr const T& operator*() const noexcept; +constexpr T& operator*() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{*this} is not valueless. + +\pnum +\returns +A reference to the owned object. +\end{itemdescr} + +\indexlibrarymember{operator->}{polymorphic}% +\begin{itemdecl} +constexpr const_pointer operator->() const noexcept; +constexpr pointer operator->() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{*this} is not valueless. + +\pnum +\returns +A pointer to the owned object. +\end{itemdescr} + +\indexlibrarymember{valueless_after_move}{polymorphic}% +\begin{itemdecl} +constexpr bool valueless_after_move() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{*this} is valueless, otherwise \tcode{false}. +\end{itemdescr} + +\indexlibrarymember{get_allocator}{polymorphic}% +\begin{itemdecl} +constexpr allocator_type get_allocator() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{alloc}. +\end{itemdescr} + +\rSec3[polymorphic.swap]{Swap} + +\indexlibrarymember{swap}{polymorphic}% +\begin{itemdecl} +constexpr void swap(polymorphic& other) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +If \tcode{allocator_traits::propagate_on_container_swap::value} +is \tcode{true}, then +\tcode{Allocator} meets the \oldconcept{Swappable} requirements. +Otherwise \tcode{get_allocator() == other.\linebreak{}get_allocator()} is \tcode{true}. + +\pnum +\effects +Swaps the states of \tcode{*this} and \tcode{other}, +exchanging owned objects or valueless states. +If \tcode{allocator_traits::propagate_on_container_swap::value} +is \tcode{true}, then +the allocators of \tcode{*this} and \tcode{other} +are exchanged by calling \tcode{swap} +as described in~\ref{swappable.requirements}. +Otherwise, +the allocators are not swapped. +\begin{note} +Does not call \tcode{swap} on the owned objects directly. +\end{note} +\end{itemdescr} + +\indexlibrarymember{swap}{polymorphic}% +%FIXME: "friend" included on declaration in synopsis but not here. +\begin{itemdecl} +constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(noexcept(lhs.swap(rhs))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{lhs.swap(rhs)}. +\end{itemdescr} + \rSec1[mem.res]{Memory resources} \rSec2[mem.res.syn]{Header \tcode{} synopsis} @@ -5610,7 +7356,7 @@ memory_resource& operator=(const memory_resource&) = default; - [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align); + void* allocate(size_t bytes, size_t alignment = max_align); void deallocate(void* p, size_t bytes, size_t alignment = max_align); bool is_equal(const memory_resource& other) const noexcept; @@ -5640,7 +7386,7 @@ \indexlibrarymember{allocate}{memory_resource}% \begin{itemdecl} -[[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align); +void* allocate(size_t bytes, size_t alignment = max_align); \end{itemdecl} \begin{itemdescr} @@ -5800,14 +7546,14 @@ polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; // \ref{mem.poly.allocator.mem}, member functions - [[nodiscard]] Tp* allocate(size_t n); + Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); - [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); + void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); - template [[nodiscard]] T* allocate_object(size_t n = 1); + template T* allocate_object(size_t n = 1); template void deallocate_object(T* p, size_t n = 1); - template [[nodiscard]] T* new_object(CtorArgs&&... ctor_args); + template T* new_object(CtorArgs&&... ctor_args); template void delete_object(T* p); template @@ -5882,7 +7628,7 @@ \indexlibrarymember{allocate}{polymorphic_allocator}% \begin{itemdecl} -[[nodiscard]] Tp* allocate(size_t n); +Tp* allocate(size_t n); \end{itemdecl} \begin{itemdescr} @@ -5919,7 +7665,7 @@ \indexlibrarymember{allocate_bytes}{polymorphic_allocator}% \begin{itemdecl} -[[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); +void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); \end{itemdecl} \begin{itemdescr} @@ -5950,7 +7696,7 @@ \indexlibrarymember{allocate_object}{polymorphic_allocator}% \begin{itemdecl} template - [[nodiscard]] T* allocate_object(size_t n = 1); + T* allocate_object(size_t n = 1); \end{itemdecl} \begin{itemdescr} @@ -5990,7 +7736,7 @@ \indexlibrarymember{new_object}{polymorphic_allocator}% \begin{itemdecl} template - [[nodiscard]] T* new_object(CtorArgs&&... ctor_args); + T* new_object(CtorArgs&&... ctor_args); \end{itemdecl} \begin{itemdescr} @@ -6803,8 +8549,8 @@ outer_allocator_type& outer_allocator() noexcept; const outer_allocator_type& outer_allocator() const noexcept; - [[nodiscard]] pointer allocate(size_type n); - [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint); + pointer allocate(size_type n); + pointer allocate(size_type n, const_void_pointer hint); void deallocate(pointer p, size_type n); size_type max_size() const; @@ -7036,7 +8782,7 @@ \indexlibrarymember{allocate}{scoped_allocator_adaptor}% \begin{itemdecl} -[[nodiscard]] pointer allocate(size_type n); +pointer allocate(size_type n); \end{itemdecl} \begin{itemdescr} @@ -7047,7 +8793,7 @@ \indexlibrarymember{allocate}{scoped_allocator_adaptor}% \begin{itemdecl} -[[nodiscard]] pointer allocate(size_type n, const_void_pointer hint); +pointer allocate(size_type n, const_void_pointer hint); \end{itemdecl} \begin{itemdescr} diff --git a/source/meta.tex b/source/meta.tex index 17cbbf91dd..95d2635ed3 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -15,7 +15,7 @@ \rSec1[intseq]{Compile-time integer sequences} -\rSec2[intseq.general]{In general} +\rSec2[intseq.general]{General} \pnum The library provides a class template that can represent an integer sequence. @@ -59,9 +59,9 @@ \pnum The alias template \tcode{make_integer_sequence} denotes a specialization of -\tcode{integer_sequence} with \tcode{N} non-type template arguments. +\tcode{integer_sequence} with \tcode{N} constant template arguments. The type \tcode{make_integer_sequence} is an alias for the type -\tcode{integer_sequence}. +\tcode{integer_sequence}. \begin{note} \tcode{make_integer_sequence} is an alias for the type \tcode{integer_sequence}. @@ -138,7 +138,7 @@ \pnum Unless otherwise specified, an incomplete type may be used to instantiate a template specified in \ref{type.traits}. -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item an instantiation of a template specified in \ref{type.traits} @@ -160,9 +160,9 @@ template struct integral_constant; template - using bool_constant = integral_constant; - using true_type = bool_constant; - using false_type = bool_constant; + using @\libglobal{bool_constant}@ = integral_constant; + using @\libglobal{true_type}@ = bool_constant; + using @\libglobal{false_type}@ = bool_constant; // \ref{meta.unary.cat}, primary type categories template struct is_void; @@ -192,8 +192,9 @@ // \ref{meta.unary.prop}, type properties template struct is_const; template struct is_volatile; - template struct is_trivial; template struct is_trivially_copyable; + template struct is_trivially_relocatable; + template struct is_replaceable; template struct is_standard_layout; template struct is_empty; template struct is_polymorphic; @@ -244,6 +245,7 @@ template struct is_nothrow_swappable; template struct is_nothrow_destructible; + template struct is_nothrow_relocatable; template struct is_implicit_lifetime; @@ -262,6 +264,7 @@ // \ref{meta.rel}, type relations template struct is_same; template struct is_base_of; + template struct is_virtual_base_of; template struct is_convertible; template struct is_nothrow_convertible; template struct is_layout_compatible; @@ -429,10 +432,10 @@ constexpr bool @\libglobal{is_const_v}@ = is_const::value; template constexpr bool @\libglobal{is_volatile_v}@ = is_volatile::value; - template - constexpr bool @\libglobal{is_trivial_v}@ = is_trivial::value; template constexpr bool @\libglobal{is_trivially_copyable_v}@ = is_trivially_copyable::value; + template + constexpr bool @\libglobal{is_trivially_relocatable_v}@ = is_trivially_relocatable::value; template constexpr bool @\libglobal{is_standard_layout_v}@ = is_standard_layout::value; template @@ -521,8 +524,12 @@ constexpr bool @\libglobal{is_nothrow_swappable_v}@ = is_nothrow_swappable::value; template constexpr bool @\libglobal{is_nothrow_destructible_v}@ = is_nothrow_destructible::value; + template + constexpr bool @\libglobal{is_nothrow_relocatable_v}@ = is_nothrow_relocatable::value; template constexpr bool @\libglobal{is_implicit_lifetime_v}@ = is_implicit_lifetime::value; + template + constexpr bool @\libglobal{is_replaceable_v}@ = is_replaceable::value; template constexpr bool @\libglobal{has_virtual_destructor_v}@ = has_virtual_destructor::value; template @@ -548,6 +555,8 @@ constexpr bool @\libglobal{is_same_v}@ = is_same::value; template constexpr bool @\libglobal{is_base_of_v}@ = is_base_of::value; + template + constexpr bool @\libglobal{is_virtual_base_of_v}@ = is_virtual_base_of::value; template constexpr bool @\libglobal{is_convertible_v}@ = is_convertible::value; template @@ -592,7 +601,7 @@ \indexlibrarymember{value_type}{integral_constant}% \begin{codeblock} namespace std { - template struct integral_constant { + template struct @\libglobal{integral_constant}@ { static constexpr T value = v; using value_type = T; @@ -604,7 +613,6 @@ } \end{codeblock} -\indexlibraryglobal{integral_constant}% \indexlibraryglobal{bool_constant}% \indexlibraryglobal{true_type}% \indexlibraryglobal{false_type}% @@ -830,13 +838,6 @@ \tcode{T} is volatile-qualified\iref{basic.type.qualifier} & \\ \rowsep -\indexlibraryglobal{is_trivial}% -\tcode{template}\br - \tcode{struct is_trivial;} & - \tcode{T} is a trivial type\iref{term.trivial.type} & - \tcode{remove_all_extents_t} shall be a complete - type or \cv{}~\keyword{void}. \\ \rowsep - \indexlibraryglobal{is_trivially_copyable}% \tcode{template}\br \tcode{struct is_trivially_copyable;} & @@ -844,6 +845,20 @@ \tcode{remove_all_extents_t} shall be a complete type or \cv{}~\keyword{void}. \\ \rowsep +\indexlibraryglobal{is_trivially_relocatable}% +\tcode{template}\br + \tcode{struct is_trivially_relocatable;} & + \tcode{T} is a trivially relocatable type\iref{basic.types.general} & + \tcode{remove_all_extents_t} shall be a complete type or + \cv{}~\keyword{void}. \\ \rowsep + +\indexlibraryglobal{is_replaceable}% +\tcode{template}\br + \tcode{struct is_replaceable;} & + \tcode{T} is a replaceable type\iref{basic.types.general} & + \tcode{remove_all_extents_t} shall be a complete type or + \cv{}~\keyword{void}. \\ \rowsep + \indexlibraryglobal{is_standard_layout}% \tcode{template}\br \tcode{struct is_standard_layout;} & @@ -875,7 +890,7 @@ \indexlibraryglobal{is_final}% \tcode{template}\br \tcode{struct is_final;} & - \tcode{T} is a class type marked with the \grammarterm{class-virt-specifier} + \tcode{T} is a class type marked with the \grammarterm{class-property-specifier} \tcode{final}\iref{class.pre}. \begin{tailnote} A union is a class type that @@ -1206,6 +1221,16 @@ \cv{}~\keyword{void}, or an array of unknown bound. \\ \rowsep +\indexlibraryglobal{is_nothrow_relocatable}% +\tcode{template}\br + \tcode{struct is_nothrow_relocatable;} & + \tcode{is_trivially_relocatable_v ||} + \tcode{(is_nothrow_move_constructible_v<} + \tcode{remove_all_extents_t> \&\& is_nothrow_destructible_v<} + \tcode{remove_all_extents_t>)} & + \tcode{remove_all_extents_t} shall be a complete type or + \cv{}~\keyword{void}, \\ \rowsep + \indexlibraryglobal{is_implicit_lifetime}% \tcode{template}\br \tcode{struct is_implicit_lifetime;} & @@ -1225,8 +1250,8 @@ For an array type \tcode{T}, the same result as \tcode{has_unique_object_representations_v>}, otherwise \seebelow. & - \tcode{T} shall be a complete type, \cv{}~\keyword{void}, or - an array of unknown bound. \\ \rowsep + \tcode{remove_all_extents_t} shall be a complete type or + \cv{}~\keyword{void}. \\ \rowsep \indexlibraryglobal{reference_constructs_from_temporary}% \tcode{template}\br @@ -1341,7 +1366,7 @@ \pnum The predicate condition for a template specialization \tcode{has_unique_object_representations} -shall be satisfied if and only if: +shall be satisfied if and only if \begin{itemize} \item \tcode{T} is trivially copyable, and \item any two objects of type \tcode{T} with the same value @@ -1463,15 +1488,31 @@ without regard to cv-qualifiers & If \tcode{Base} and \tcode{Derived} are non-union class types and are -not (possibly cv-qualified versions of) the same type, + not (possibly cv-qualified versions of) the same type, \tcode{Derived} shall be a complete type. \begin{tailnote} -Base classes that are private, protected, or ambiguous + Base classes that are private, protected, or ambiguous are, nonetheless, base classes. \end{tailnote} \\ \rowsep +\indexlibraryglobal{is_virtual_base_of}% +\tcode{template}\br + \tcode{struct is_virtual_base_of;} & + \tcode{Base} is a virtual base class of \tcode{Derived}\iref{class.mi} + without regard to cv-qualifiers. & + If \tcode{Base} and + \tcode{Derived} are non-union class types, + \tcode{Derived} shall be a complete type. + \begin{note} + Virtual base classes that are private, protected, or ambiguous + are, nonetheless, virtual base classes. + \end{note} + \begin{tailnote} + A class is never a virtual base class of itself. + \end{tailnote} \\ \rowsep + \indexlibraryglobal{is_convertible}% \tcode{template}\br \tcode{struct is_convertible;} & @@ -1486,7 +1527,7 @@ the conversion, as defined by \tcode{is_convertible}, is known not to throw any exceptions\iref{expr.unary.noexcept} & \tcode{From} and \tcode{To} shall be complete types, - \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep + \cv{}~\keyword{void}, or arrays of unknown bound. \\ \rowsep \indexlibraryglobal{is_layout_compatible}% \tcode{template}\br @@ -1888,21 +1929,18 @@ \lhdr{Template} & \rhdr{Comments} \\ \capsep \endhead -\indexlibraryglobal{type_identity}% \tcode{template\br - struct type_identity;} + struct \libglobal{type_identity};} & The member typedef \tcode{type} denotes \tcode{T}. \\ \rowsep -\indexlibraryglobal{remove_cvref}% -\tcode{template\br struct remove_cvref;} +\tcode{template\br struct \libglobal{remove_cvref};} & The member typedef \tcode{type} denotes \tcode{remove_cv_t>}. \\ \rowsep -\indexlibraryglobal{decay}% -\tcode{template\br struct decay;} +\tcode{template\br struct \libglobal{decay};} & Let \tcode{U} be \tcode{remove_reference_t}. If \tcode{is_array_v} is \tcode{true}, the member typedef \tcode{type} denotes @@ -1918,8 +1956,7 @@ \end{tailnote} \\ \rowsep -\indexlibraryglobal{enable_if}% -\tcode{template} \tcode{struct enable_if;} +\tcode{template} \tcode{struct \libglobal{enable_if};} & If \tcode{B} is \tcode{true}, the member typedef \tcode{type} denotes \tcode{T}; otherwise, there shall be no member @@ -1927,49 +1964,45 @@ \tcode{template}\br - \tcode{struct conditional;} + \tcode{struct \libglobal{conditional};} & If \tcode{B} is \tcode{true}, the member typedef \tcode{type} denotes \tcode{T}. If \tcode{B} is \tcode{false}, the member typedef \tcode{type} denotes \tcode{F}. \\ \rowsep \tcode{template} \tcode{struct common_type;} & - Unless this trait is specialized (as specified in Note B, below), - the member \tcode{type} is defined or omitted as specified in Note A, below. + Unless this trait is specialized, + the member \tcode{type} is defined or omitted as specified below. If it is omitted, there shall be no member \tcode{type}. Each type in the template parameter pack \tcode{T} shall be complete, \cv{}~\keyword{void}, or an array of unknown bound. \\ \rowsep -\indexlibraryglobal{basic_common_reference}% \tcode{template class,} \hspace*{2ex}\tcode{template class>} \keyword{struct} - \hspace*{2ex}\tcode{basic_common_reference;} + \hspace*{2ex}\tcode{\libglobal{basic_common_reference};} & - Unless this trait is specialized (as specified in Note D, below), + Unless this trait is specialized, there shall be no member \tcode{type}. \\ \rowsep -\indexlibraryglobal{common_reference}% -\tcode{template} \tcode{struct common_reference;} +\tcode{template} \tcode{struct \libglobal{common_reference};} & The member \grammarterm{typedef-name} \tcode{type} is defined or omitted - as specified in Note C, below. Each type in the parameter pack \tcode{T} shall + as specified below. Each type in the parameter pack \tcode{T} shall be complete or \cv{} \keyword{void}. \\ \rowsep -\indexlibraryglobal{underlying_type}% \tcode{template}\br - \tcode{struct underlying_type;} + \tcode{struct \libglobal{underlying_type};} & If \tcode{T} is an enumeration type, the member typedef \tcode{type} denotes the underlying type of \tcode{T}\iref{dcl.enum}; otherwise, there is no member \tcode{type}.\br \mandates \tcode{T} is not an incomplete enumeration type. \\ \rowsep -\indexlibraryglobal{invoke_result}% \tcode{template}\br - \tcode{struct invoke_result;} + \tcode{struct \libglobal{invoke_result};} & If the expression \tcode{\placeholdernc{INVOKE}(declval(), declval()...)}\iref{func.require} is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}, @@ -1990,8 +2023,7 @@ are complete types, \cv{}~\keyword{void}, or arrays of unknown bound.\\ \rowsep -\indexlibraryglobal{unwrap_reference}% -\tcode{template} \tcode{struct unwrap_reference;} +\tcode{template} \tcode{struct \libglobal{unwrap_reference};} & If \tcode{T} is a specialization \tcode{reference_wrapper} for some type \tcode{X}, @@ -1999,8 +2031,7 @@ denotes \tcode{X\&}, otherwise \tcode{type} denotes \tcode{T}. \\ \rowsep -\indexlibraryglobal{unwrap_ref_decay}% -\tcode{template} \tcode{unwrap_ref_decay;} +\tcode{template} \tcode{\libglobal{unwrap_ref_decay};} & The member typedef \tcode{type} of \tcode{unwrap_ref_decay} denotes the type \tcode{unwrap_reference_t>}.\\ @@ -2066,7 +2097,6 @@ \tcode{\placeholdernc{COMMON-REF}(A, B)} is ill-formed. \pnum -Note A: For the \tcode{common_type} trait applied to a template parameter pack \tcode{T} of types, the member \tcode{type} shall be either defined or not present as follows: @@ -2120,7 +2150,7 @@ \end{itemize} \pnum -Note B: Notwithstanding the provisions of \ref{meta.type.synop}, and +Notwithstanding the provisions of \ref{meta.type.synop}, and pursuant to \ref{namespace.std}, a program may specialize \tcode{common_type} for types \tcode{T1} and \tcode{T2} such that @@ -2140,7 +2170,7 @@ No diagnostic is required for a violation of this Note's rules. \pnum -Note C: For the \tcode{common_reference} trait applied to a parameter pack +For the \tcode{common_reference} trait applied to a parameter pack \tcode{T} of types, the member \tcode{type} shall be either defined or not present as follows: \begin{itemize} @@ -2186,7 +2216,7 @@ \end{itemize} \pnum -Note D: Notwithstanding the provisions of \ref{meta.type.synop}, and +Notwithstanding the provisions of \ref{meta.type.synop}, and pursuant to \ref{namespace.std}, a program may partially specialize \tcode{basic_common_reference} for types \tcode{T} and \tcode{U} such that @@ -2504,7 +2534,7 @@ } } - constexpr auto operator*() -> bool& { + constexpr auto operator*() const -> const bool& { return b; } }; @@ -2520,7 +2550,7 @@ \rSec1[ratio]{Compile-time rational arithmetic} -\rSec2[ratio.general]{In general} +\rSec2[ratio.general]{General} \pnum \indexlibraryglobal{ratio}% diff --git a/source/modules.tex b/source/modules.tex index 52873a37ae..a0386b38ca 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -312,7 +312,7 @@ A redeclaration of an entity $X$ is implicitly exported if $X$ was introduced by an exported declaration; -otherwise it shall not be exported. +otherwise it shall not be exported unless it is a namespace. \begin{example} \begin{codeblock} export module M; @@ -320,6 +320,12 @@ typedef S S; export typedef S S; // OK, does not redeclare an entity export struct S; // error: exported declaration follows non-exported declaration +namespace N { // external linkage, attached to global module, not exported + void f(); +} +namespace N { // OK, exported namespace redeclaring non-exported namespace + export void g(); +} \end{codeblock} \end{example} @@ -593,7 +599,7 @@ \pnum A declaration $D$ is \defn{decl-reachable} from a declaration $S$ -in the same translation unit if: +in the same translation unit if \begin{itemize} \item $D$ does not declare a function or function template and diff --git a/source/numerics.tex b/source/numerics.tex index e08036998a..5d2ee0f222 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17,15 +17,16 @@ as summarized in \tref{numerics.summary}. \begin{libsumtab}{Numerics library summary}{numerics.summary} -\ref{numeric.requirements} & Requirements & \\ \rowsep -\ref{cfenv} & Floating-point environment & \tcode{} \\ \rowsep -\ref{complex.numbers} & Complex numbers & \tcode{} \\ \rowsep -\ref{rand} & Random number generation & \tcode{} \\ \rowsep -\ref{numarray} & Numeric arrays & \tcode{} \\ \rowsep -\ref{c.math} & Mathematical functions for floating-point types & - \tcode{}, \tcode{} \\ \rowsep -\ref{numbers} & Numbers & \tcode{} \\ \rowsep -\ref{linalg} & Linear algebra & \tcode{} \\ +\ref{numeric.requirements} & Requirements & \\ \rowsep +\ref{cfenv} & Floating-point environment & \tcode{} \\ \rowsep +\ref{complex.numbers} & Complex numbers & \tcode{} \\ \rowsep +\ref{rand} & Random number generation & \tcode{} \\ \rowsep +\ref{numarray} & Numeric arrays & \tcode{} \\ \rowsep +\ref{c.math} & Mathematical functions for + floating-point types & \tcode{}, \tcode{} \\ \rowsep +\ref{numbers} & Numbers & \tcode{} \\ \rowsep +\ref{linalg} & Linear algebra & \tcode{} \\ \rowsep +\ref{simd} & Data-parallel types & \tcode{} \\ \end{libsumtab} \rSec1[numeric.requirements]{Numeric type requirements} @@ -97,31 +98,20 @@ \indexlibraryglobal{feholdexcept}% \indexlibraryglobal{fesetenv}% \indexlibraryglobal{feupdateenv}% -\indexlibraryglobal{FE_ALL_EXCEPT}% -\indexlibraryglobal{FE_DIVBYZERO}% -\indexlibraryglobal{FE_INEXACT}% -\indexlibraryglobal{FE_INVALID}% -\indexlibraryglobal{FE_OVERFLOW}% -\indexlibraryglobal{FE_UNDERFLOW}% -\indexlibraryglobal{FE_DOWNWARD}% -\indexlibraryglobal{FE_TONEAREST}% -\indexlibraryglobal{FE_TOWARDZERO}% -\indexlibraryglobal{FE_UPWARD}% -\indexlibraryglobal{FE_DFL_ENV}% -\begin{codeblock} -#define FE_ALL_EXCEPT @\seebelow@ -#define FE_DIVBYZERO @\seebelow@ // optional -#define FE_INEXACT @\seebelow@ // optional -#define FE_INVALID @\seebelow@ // optional -#define FE_OVERFLOW @\seebelow@ // optional -#define FE_UNDERFLOW @\seebelow@ // optional - -#define FE_DOWNWARD @\seebelow@ // optional -#define FE_TONEAREST @\seebelow@ // optional -#define FE_TOWARDZERO @\seebelow@ // optional -#define FE_UPWARD @\seebelow@ // optional - -#define FE_DFL_ENV @\seebelow@ +\begin{codeblock} +#define @\libmacro{FE_ALL_EXCEPT}@ @\seebelow@ +#define @\libmacro{FE_DIVBYZERO}@ @\seebelow@ // optional +#define @\libmacro{FE_INEXACT}@ @\seebelow@ // optional +#define @\libmacro{FE_INVALID}@ @\seebelow@ // optional +#define @\libmacro{FE_OVERFLOW}@ @\seebelow@ // optional +#define @\libmacro{FE_UNDERFLOW}@ @\seebelow@ // optional + +#define @\libmacro{FE_DOWNWARD}@ @\seebelow@ // optional +#define @\libmacro{FE_TONEAREST}@ @\seebelow@ // optional +#define @\libmacro{FE_TOWARDZERO}@ @\seebelow@ // optional +#define @\libmacro{FE_UPWARD}@ @\seebelow@ // optional + +#define @\libmacro{FE_DFL_ENV}@ @\seebelow@ namespace std { // types @@ -212,8 +202,8 @@ Moreover, if \tcode{a} is an expression of type \cv{}~\tcode{complex*} and the expression \tcode{a[i]} is well-defined for an integer expression \tcode{i}, then: \begin{itemize} -\item \tcode{reinterpret_cast<\cv{} T*>(a)[2*i]} designates the real part of \tcode{a[i]}, and -\item \tcode{reinterpret_cast<\cv{} T*>(a)[2*i + 1]} designates the imaginary part of \tcode{a[i]}. +\item \tcode{reinterpret_cast<\cv{} T*>(a)[2 * i]} designates the real part of \tcode{a[i]}, and +\item \tcode{reinterpret_cast<\cv{} T*>(a)[2 * i + 1]} designates the imaginary part of \tcode{a[i]}. \end{itemize} \rSec2[complex.syn]{Header \tcode{} synopsis} @@ -306,14 +296,14 @@ // \ref{complex.literals}, complex literals inline namespace literals { - inline namespace complex_literals { - constexpr complex operator""il(long double); - constexpr complex operator""il(unsigned long long); - constexpr complex operator""i(long double); - constexpr complex operator""i(unsigned long long); - constexpr complex operator""if(long double); - constexpr complex operator""if(unsigned long long); - } + inline namespace complex_literals { + constexpr complex operator""il(long double); + constexpr complex operator""il(unsigned long long); + constexpr complex operator""i(long double); + constexpr complex operator""i(unsigned long long); + constexpr complex operator""if(long double); + constexpr complex operator""if(unsigned long long); + } } } \end{codeblock} @@ -1211,8 +1201,10 @@ Function template \tcode{pow} has additional constexpr overloads sufficient to ensure, for a call with one argument of type \tcode{complex} and the other argument of type \tcode{T2} or \tcode{complex}, -both arguments are effectively cast to \tcode{complex>}. -If \tcode{common_type_t} is not well-formed, +both arguments are effectively cast to \tcode{complex>}, +where \tcode{T3} is +\tcode{double} if \tcode{T2} is an integer type and \tcode{T2} otherwise. +If \tcode{common_type_t} is not well-formed, then the program is ill-formed. \rSec2[complex.literals]{Suffixes for complex number literals} @@ -1380,11 +1372,11 @@ namespace std { // \ref{rand.req.urng}, uniform random bit generator requirements template - concept uniform_random_bit_generator = @\seebelow@; + concept uniform_random_bit_generator = @\seebelow@; // freestanding // \ref{rand.eng.lcong}, class template \tcode{linear_congruential_engine} template - class linear_congruential_engine; + class linear_congruential_engine; // partially freestanding // \ref{rand.eng.mers}, class template \tcode{mersenne_twister_engine} template - class subtract_with_carry_engine; + class subtract_with_carry_engine; // partially freestanding // \ref{rand.adapt.disc}, class template \tcode{discard_block_engine} template - class discard_block_engine; + class discard_block_engine; // partially freestanding // \ref{rand.adapt.ibits}, class template \tcode{independent_bits_engine} template - class independent_bits_engine; + class independent_bits_engine; // partially freestanding // \ref{rand.adapt.shuf}, class template \tcode{shuffle_order_engine} template class shuffle_order_engine; + // \ref{rand.eng.philox}, class template \tcode{philox_engine} + template + class philox_engine; + // \ref{rand.predef}, engines and engine adaptors with predefined parameters - using minstd_rand0 = @\seebelow@; - using minstd_rand = @\seebelow@; - using mt19937 = @\seebelow@; - using mt19937_64 = @\seebelow@; - using ranlux24_base = @\seebelow@; - using ranlux48_base = @\seebelow@; - using ranlux24 = @\seebelow@; - using ranlux48 = @\seebelow@; + using minstd_rand0 = @\seebelow@; // freestanding + using minstd_rand = @\seebelow@; // freestanding + using mt19937 = @\seebelow@; // freestanding + using mt19937_64 = @\seebelow@; // freestanding + using ranlux24_base = @\seebelow@; // freestanding + using ranlux48_base = @\seebelow@; // freestanding + using ranlux24 = @\seebelow@; // freestanding + using ranlux48 = @\seebelow@; // freestanding using knuth_b = @\seebelow@; + using philox4x32 = @\seebelow@; + using philox4x64 = @\seebelow@; using default_random_engine = @\seebelow@; @@ -1445,17 +1443,19 @@ template requires @\libconcept{output_range}@> && @\libconcept{invocable}@ && - @\libconcept{uniform_random_bit_generator}@> + @\libconcept{uniform_random_bit_generator}@> && + is_arithmetic_v> constexpr borrowed_iterator_t generate_random(R&& r, G&& g, D&& d); template> O, @\libconcept{sentinel_for}@ S> - requires @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> + requires @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> && + is_arithmetic_v> constexpr O generate_random(O first, S last, G&& g, D&& d); } // \ref{rand.dist.uni.int}, class template \tcode{uniform_int_distribution} template - class uniform_int_distribution; + class uniform_int_distribution; // partially freestanding // \ref{rand.dist.uni.real}, class template \tcode{uniform_real_distribution} template @@ -1556,7 +1556,7 @@ \rSec3[rand.req.genl]{General requirements}% \pnum -Throughout this subclause \ref{rand}, +Throughout \ref{rand}, the effect of instantiating a template: \begin{itemize} \item @@ -1616,7 +1616,7 @@ \end{itemize} \pnum -Throughout this subclause \ref{rand}, +Throughout \ref{rand}, phrases of the form ``\tcode{x} is an iterator of a specific kind'' shall be interpreted as equivalent to the more formal requirement that ``\tcode{x} is a value @@ -1624,7 +1624,7 @@ of the specified iterator type''. \pnum -Throughout this subclause \ref{rand}, +Throughout \ref{rand}, any constructor that can be called with a single argument and that meets a requirement specified in this subclause shall be declared \keyword{explicit}. @@ -1659,8 +1659,8 @@ in \tref{rand.req.seedseq} are valid and have the indicated semantics, and if \tcode{S} also meets all other requirements -of this subclause \ref{rand.req.seedseq}. -In that Table and throughout this subclause: +of \ref{rand.req.seedseq}. +In \tref{rand.req.seedseq} and throughout this subclause: \begin{itemize} \item \tcode{T} is the type named by @@ -1705,7 +1705,7 @@ & \tcode{T} & \tcode{T} is an unsigned integer type\iref{basic.fundamental} of at least 32 bits. - & compile-time + & \\ \rowsep \tcode{S()}% & @@ -1875,8 +1875,8 @@ in \tref{rand.req.eng} are valid and have the indicated semantics, and if \tcode{E} also meets all other requirements -of this subclause \ref{rand.req.eng}. -In that Table and throughout this subclause: +of \ref{rand.req.eng}. +In \tref{rand.req.eng} and throughout this subclause: \begin{itemize} \item \tcode{T} is the type named by @@ -1914,7 +1914,8 @@ & \rhdr{Complexity} \\ \capsep \endfirsthead -\hline +\continuedcaption\\ +\topline \lhdr{Expression} & \chdr{Return type} & \chdr{Pre/post-condition} @@ -2020,51 +2021,6 @@ & \tcode{bool} & \tcode{!(x == y)}. & \bigoh{$\text{size of state}$} - \\ \rowsep -\tcode{os << x}% - & reference to the type of \tcode{os} - & With \tcode{os.}\textit{fmtflags} set to - \tcode{ios_base::dec|ios_base::left} - and the fill character set to the space character, - writes to \tcode{os} - the textual representation - of \tcode{x}'s current state. - In the output, - adjacent numbers are separated - by one or more space characters. - - \ensures The \tcode{os.}\textit{fmtflags} and fill character are unchanged. - & \bigoh{$\text{size of state}$} - \\ \rowsep -\tcode{is >> v}% - & reference to the type of \tcode{is} - & With \tcode{is.fmtflags} - set to \tcode{ios_base::dec}, - sets \tcode{v}'s state - as determined by reading its textual representation from \tcode{is}. - If bad input is encountered, - ensures that \tcode{v}'s state is unchanged by the operation - and - calls \tcode{is.setstate(ios_base::failbit)} - (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). - If a textual representation written via \tcode{os << x} - was subsequently read via \tcode{is >> v}, - then \tcode{x == v} - provided that there have been no intervening invocations - of \tcode{x} or of \tcode{v}. - - \expects - \tcode{is} provides a textual representation - that was previously written - using an output stream - whose imbued locale - was the same as that of \tcode{is}, - and whose type's template specialization arguments - \tcode{charT} and \tcode{traits} - were respectively the same as those of \tcode{is}. - - \ensures The \tcode{is.}\textit{fmtflags} are unchanged. - & \bigoh{$\text{size of state}$} \\ \end{libreqtab4d} @@ -2075,6 +2031,93 @@ These operations shall each be of complexity no worse than \bigoh{\text{size of state}}. +\pnum +On hosted implementations, +the following expressions are well-formed and have the specified semantics. + +\begin{itemdecl} +os << x +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +With \tcode{os.\placeholdernc{fmtflags}} set to +\tcode{ios_base::dec|ios_base::left} +and the fill character set to the space character, +writes to \tcode{os} +the textual representation +of \tcode{x}'s current state. +In the output, +adjacent numbers are separated +by one or more space characters. + +\pnum +\ensures +The \tcode{os.\placeholdernc{fmtflags}} and fill character are unchanged. + +\pnum +\result +reference to the type of \tcode{os}. + +\pnum +\returns +\tcode{os}. + +\pnum +\complexity +\bigoh{$\text{size of state}$} +\end{itemdescr} + +\begin{itemdecl} +is >> v +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{is} provides a textual representation +that was previously written +using an output stream +whose imbued locale +was the same as that of \tcode{is}, +and whose type's template specialization arguments +\tcode{charT} and \tcode{traits} +were respectively the same as those of \tcode{is}. + +\pnum +\effects +With \tcode{is.\placeholdernc{fmtflags}} +set to \tcode{ios_base::dec}, +sets \tcode{v}'s state +as determined by reading its textual representation from \tcode{is}. +If bad input is encountered, +ensures that \tcode{v}'s state is unchanged by the operation +and +calls \tcode{is.setstate(ios_base::failbit)} +(which may throw \tcode{ios_base::failure}\iref{iostate.flags}). +If a textual representation written via \tcode{os << x} +was subsequently read via \tcode{is >> v}, +then \tcode{x == v} +provided that there have been no intervening invocations +of \tcode{x} or of \tcode{v}. + +\pnum +\ensures +The \tcode{is.\placeholdernc{fmtflags}} are unchanged. + +\pnum +\result +reference to the type of \tcode{is}. + +\pnum +\returns +\tcode{is}. + +\pnum +\complexity +\bigoh{$\text{size of state}$} +\end{itemdescr} \indextext{requirements!random number engine|)} \indextext{random number engine!requirements|)}% @@ -2254,8 +2297,8 @@ are valid and have the indicated semantics, and if \tcode{D} and its associated types also meet all other requirements -of this subclause \ref{rand.req.dist}. -In that Table and throughout this subclause, +of \ref{rand.req.dist}. +In \tref{rand.req.dist} and throughout this subclause, \begin{itemize} \item \tcode{T} is the type named by @@ -2302,7 +2345,8 @@ & \rhdr{Complexity} \\ \capsep \endfirsthead -\hline +\continuedcaption\\ +\topline \lhdr{Expression} & \chdr{Return type} & \chdr{Pre/post-condition} @@ -2312,12 +2356,12 @@ \tcode{D::result_type} & \tcode{T} & \tcode{T} is an arithmetic type\iref{basic.fundamental}. - & compile-time + & \\ \rowsep \tcode{D::param_type} & \tcode{P} & - & compile-time + & \\ \rowsep \tcode{D()}% & @@ -2406,35 +2450,6 @@ & \tcode{bool} & \tcode{!(x == y)}. & same as \tcode{x == y}. - \\ \rowsep -\tcode{os << x} - & reference to the type of \tcode{os} - & Writes to \tcode{os} a textual representation - for the parameters and the additional internal data of \tcode{x}. - - \ensures The \tcode{os.}\textit{fmtflags} and fill character are unchanged. - & - \\ \rowsep -\tcode{is >> d} - & reference to the type of \tcode{is} - & Restores from \tcode{is} - the parameters and additional internal data of the lvalue \tcode{d}. - If bad input is encountered, - ensures that \tcode{d} is unchanged by the operation - and - calls \tcode{is.setstate(ios_base::failbit)} - (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). - - \expects - \tcode{is} provides a textual representation - that was previously written - using an \tcode{os} whose imbued locale - and whose type's template specialization arguments - \tcode{charT} and \tcode{traits} - were the same as those of \tcode{is}. - - \ensures The \tcode{is.}\textit{fmtflags} are unchanged. - & \\ \end{libreqtab4d} @@ -2465,7 +2480,7 @@ It is unspecified whether \tcode{D::param_type} is declared as a (nested) \keyword{class} or via a \keyword{typedef}. -In this subclause \ref{rand}, +In \ref{rand}, declarations of \tcode{D::param_type} are in the form of \keyword{typedef}s for convenience of exposition only. @@ -2495,6 +2510,70 @@ using distribution_type = D; \end{codeblock} +\pnum +On hosted implementations, +the following expressions are well-formed and have the specified semantics. + +\begin{itemdecl} +os << x +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Writes to \tcode{os} a textual representation +for the parameters and the additional internal data of \tcode{x}. + +\pnum +\ensures +The \tcode{os.\placeholdernc{fmtflags}} and fill character are unchanged. + +\pnum +\result +reference to the type of \tcode{os}. + +\pnum +\returns +\tcode{os}. +\end{itemdescr} + +\begin{itemdecl} +is >> d +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{is} provides a textual representation +that was previously written +using an \tcode{os} whose imbued locale +and whose type's template specialization arguments +\tcode{charT} and \tcode{traits} +were the same as those of \tcode{is}. + +\pnum +\effects +Restores from \tcode{is} +the parameters and additional internal data of the lvalue \tcode{d}. +If bad input is encountered, +ensures that \tcode{d} is unchanged by the operation +and +calls \tcode{is.setstate(ios_base::failbit)} +(which may throw \tcode{ios_base::failure}\iref{iostate.flags}). + +\pnum +\ensures +The \tcode{is.\placeholdernc{fmtflags}} are unchanged. + +\pnum +\result +reference to the type of \tcode{is}. + +\pnum +\returns +\tcode{is}. +\end{itemdescr} + \indextext{requirements!random number distribution|)}% \indextext{random number distribution!requirements|)}% \indextext{random number generation!requirements|)} @@ -2553,7 +2632,7 @@ \pnum Each template specified in \ref{rand.eng} requires one or more relationships, -involving the value(s) of its non-type template parameter(s), to hold. +involving the value(s) of its constant template parameter(s), to hold. A program instantiating any of these templates is ill-formed if any such required relationship fails to hold. @@ -2638,10 +2717,12 @@ // inserters and extractors template friend basic_ostream& - operator<<(basic_ostream& os, const linear_congruential_engine& x); + operator<<(basic_ostream& os, // hosted + const linear_congruential_engine& x); template friend basic_istream& - operator>>(basic_istream& is, linear_congruential_engine& x); + operator>>(basic_istream& is, // hosted + linear_congruential_engine& x); }; } \end{codeblock} @@ -2650,7 +2731,7 @@ If the template parameter \tcode{m} is $0$, the modulus $m$ -used throughout this subclause~\ref{rand.eng.lcong} +used throughout \ref{rand.eng.lcong} is \tcode{numeric_limits::max()} plus $1$. \begin{note} $m$ need not be representable @@ -2818,10 +2899,12 @@ // inserters and extractors template friend basic_ostream& - operator<<(basic_ostream& os, const mersenne_twister_engine& x); + operator<<(basic_ostream& os, // hosted + const mersenne_twister_engine& x); template friend basic_istream& - operator>>(basic_istream& is, mersenne_twister_engine& x); + operator>>(basic_istream& is, // hosted + mersenne_twister_engine& x); }; } \end{codeblock} @@ -2837,12 +2920,12 @@ \tcode{t <= w}, \tcode{l <= w}, \tcode{w <= numeric_limits::digits}, - \tcode{a <= (1u< friend basic_ostream& - operator<<(basic_ostream& os, const subtract_with_carry_engine& x); + operator<<(basic_ostream& os, // hosted + const subtract_with_carry_engine& x); template friend basic_istream& - operator>>(basic_istream& is, subtract_with_carry_engine& x); + operator>>(basic_istream& is, // hosted + subtract_with_carry_engine& x); }; } \end{codeblock} @@ -3025,8 +3110,8 @@ first construct \tcode{e}, a \tcode{linear_congruential_engine} object, as if by the following definition: \begin{codeblock} -linear_congruential_engine e(value == 0u ? default_seed : value); +linear_congruential_engine e( + value == 0u ? default_seed : static_cast(value % 2147483563u)); \end{codeblock} Then, to set each $X_k$, obtain new values $z_0, \dotsc, z_{n-1}$ @@ -3061,6 +3146,237 @@ otherwise sets $c$ to $0$. \end{itemdescr} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% philox_engine engine: + +\rSec3[rand.eng.philox]{Class template \tcode{philox_engine}}% +\indexlibraryglobal{philox_engine}% + +\pnum +A \tcode{philox_engine} random number engine produces +unsigned integer random numbers in the interval \range{0}{$m$}, +where $m = 2^w$ and +the template parameter $w$ defines the range of the produced numbers. +The state of a \tcode{philox_engine} object consists of +a sequence $X$ of $n$ unsigned integer values of width $w$, +a sequence $K$ of $n/2$ values of \tcode{result_type}, +a sequence $Y$ of $n$ values of \tcode{result_type}, and +a scalar $i$, where +\begin{itemize} +\item +$X$ is the interpretation of the unsigned integer \term{counter} value +$Z \cedef \sum_{j = 0}^{n - 1} X_j \cdot 2^{wj}$ of $n \cdot w$ bits, +\item +$K$ are keys, which are generated once from the seed (see constructors below) +and remain constant unless the \tcode{seed} function\iref{rand.req.eng} is invoked, +\item +$Y$ stores a batch of output values, and +\item +$i$ is an index for an element of the sequence $Y$. +\end{itemize} + +\pnum +The generation algorithm returns $Y_i$, +the value stored in the $i^{th}$ element of $Y$ after applying +the transition algorithm. + +\pnum +The state transition is performed as if by the following algorithm: +\begin{codeblock} +@$i$@ = @$i$@ + 1 +if (@$i$@ == @$n$@) { + @$Y$@ = Philox(@$K$@, @$X$@) // \seebelow + @$Z$@ = @$Z$@ + 1 + @$i$@ = 0 +} +\end{codeblock} + +\pnum +The \tcode{Philox} function maps the length-$n/2$ sequence $K$ and +the length-$n$ sequence $X$ into a length-$n$ output sequence $Y$. +Philox applies an $r$-round substitution-permutation network to the values in $X$. +A single round of the generation algorithm performs the following steps: +\begin{itemize} +\item +The output sequence $X'$ of the previous round +($X$ in case of the first round) +is permuted to obtain the intermediate state $V$: +\begin{codeblock} +@$V_j = X'_{f_n(j)}$@ +\end{codeblock} +where $j = 0, \dotsc, n - 1$ and +$f_n(j)$ is defined in \tref{rand.eng.philox.f}. + +\begin{floattable}{Values for the word permutation $\bm{f}_{\bm{n}}\bm{(j)}$}{rand.eng.philox.f} +{l|l|l|l|l|l} +\topline + \multicolumn{2}{|c|}{$\bm{f}_{\bm{n}}\bm{(j)}$} & \multicolumn{4}{c|}{$\bm{j}$} \\ \cline{3-6} + \multicolumn{2}{|c|}{} + & 0 & 1 & 2 & 3 \\ \hline + $\bm{n} $ & 2 & 0 & 1 & \multicolumn{2}{c|}{} \\ \cline{2-6} + & 4 & 2 & 1 & 0 & 3 \\ \cline{2-6} +\end{floattable} +\begin{note} +For $n = 2$ the sequence is not permuted. +\end{note} + +\item +The following computations are applied to the elements of the $V$ sequence: +\begin{codeblock} +@$X_{2k + 0} = \mulhi(V_{2k}, M_{k}, w) \xor \mathit{key}^q_k \xor V_{2k + 1}$@ +@$X_{2k + 1} = \mullo(V_{2k}, M_{k}, w)$@ +\end{codeblock} +where: + \begin{itemize} + \item + $\mullo(\tcode{a}, \tcode{b}, \tcode{w})$ is + the low half of the modular multiplication of \tcode{a} and \tcode{b}: + $(\tcode{a} \cdot \tcode{b}) \mod 2^w$, + + \item + $\mulhi(\tcode{a}, \tcode{b}, \tcode{w})$ is + the high half of the modular multiplication of \tcode{a} and \tcode{b}: + $(\left\lfloor (\tcode{a} \cdot \tcode{b}) / 2^w \right\rfloor)$, + + \item + $k = 0, \dotsc, n/2 - 1$ is the index in the sequences, + + \item + $q = 0, \dotsc, r - 1$ is the index of the round, + + \item + $\mathit{key}^q_k$ is the $k^\text{th}$ round key for round $q$, + $\mathit{key}^q_k \cedef (K_k + q \cdot C_k) \mod 2^w$, + + \item + $K_k$ are the elements of the key sequence $K$, + + \item + $M_k$ is \tcode{multipliers[$k$]}, and + + \item + $C_k$ is \tcode{round_consts[$k$]}. + \end{itemize} +\end{itemize} + +\pnum +After $r$ applications of the single-round function, +\tcode{Philox} returns the sequence $Y = X'$. + +\indexlibraryglobal{philox_engine}% +\indexlibrarymember{result_type}{philox_engine}% +\begin{codeblock} +namespace std { + template + class philox_engine { + static constexpr size_t @\exposid{array-size}@ = n / 2; // \expos + public: + // types + using result_type = UIntType; + + // engine characteristics + static constexpr size_t word_size = w; + static constexpr size_t word_count = n; + static constexpr size_t round_count = r; + static constexpr array multipliers; + static constexpr array}@ round_consts; + static constexpr result_type min() { return 0; } + static constexpr result_type max() { return m - 1; } + static constexpr result_type default_seed = 20111115u; + + // constructors and seeding functions + philox_engine() : philox_engine(default_seed) {} + explicit philox_engine(result_type value); + template explicit philox_engine(Sseq& q); + void seed(result_type value = default_seed); + template void seed(Sseq& q); + + void set_counter(const array& counter); + + // equality operators + friend bool operator==(const philox_engine& x, const philox_engine& y); + + // generating functions + result_type operator()(); + void discard(unsigned long long z); + + // inserters and extractors + template + friend basic_ostream& + operator<<(basic_ostream& os, const philox_engine& x); + template + friend basic_istream& + operator>>(basic_istream& is, philox_engine& x); + }; +} +\end{codeblock} + +\pnum +\mandates +\begin{itemize} +\item \tcode{sizeof...(consts) == n} is \tcode{true}, and +\item \tcode{n == 2 || n == 4} is \tcode{true}, and +\item \tcode{0 < r} is \tcode{true}, and +\item \tcode{0 < w \&\& w <= numeric_limits::digits} is \tcode{true}. +\end{itemize} + +\pnum +The template parameter pack \tcode{consts} represents +the $M_k$ and $C_k$ constants which are grouped as follows: +$[ M_0, C_0, M_1, C_1, M_2, C_2, \dotsc, M_{n/2 - 1}, C_{n/2 - 1} ]$. + +\pnum +The textual representation consists of the values of +$K_0, \dotsc, K_{n/2 - 1}, X_{0}, \dotsc, X_{n - 1}, i$, in that order. +\begin{note} +The stream extraction operator can reconstruct $Y$ from $K$ and $X$, as needed. +\end{note} + +\indexlibraryctor{philox_engine} +\begin{itemdecl} +explicit philox_engine(result_type value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sets the $K_0$ element of sequence $K$ to $\tcode{value} \mod 2^w$. +All elements of sequences $X$ and $K$ (except $K_0$) are set to \tcode{0}. +The value of $i$ is set to $n - 1$. +\end{itemdescr} + +\indexlibraryctor{philox_engine} +\begin{itemdecl} +template explicit philox_engine(Sseq& q); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +With $p = \left\lceil w / 32 \right\rceil$ and +an array (or equivalent) \tcode{a} of length $(n/2) \cdot p$, +invokes \tcode{q.generate(a + 0, a + n / 2 * $p$)} and +then iteratively for $k = 0, \dotsc, n/2 - 1$, +sets $K_k$ to +$\left(\sum_{j = 0}^{p - 1} a_{k p + j} \cdot 2^{32j} \right) \mod 2^w$. +All elements of sequence $X$ are set to \tcode{0}. +The value of $i$ is set to $n - 1$. +\end{itemdescr} + +\indexlibrarymember{set_counter}{philox_engine}% +\begin{itemdecl} +void set_counter(const array& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +For $j = 0, \dotsc, n - 1$ sets $X_j$ to $C_{n - 1 - j} \mod 2^w$. +The value of $i$ is set to $n - 1$. +\begin{note} +The counter is the value $Z$ introduced at the beginning of this subclause. +\end{note} +\end{itemdescr} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3073,34 +3389,34 @@ \rSec2[rand.adapt]{Random number engine adaptor class templates} -\rSec3[rand.adapt.general]{In general} +\rSec3[rand.adapt.general]{General} \pnum Each type instantiated -from a class template specified in this subclause~\ref{rand.adapt} +from a class template specified in \ref{rand.adapt} meets the requirements of a random number engine adaptor\iref{rand.req.adapt} type. \pnum Except where specified otherwise, the complexity of each function -specified in this subclause~\ref{rand.adapt} +specified in \ref{rand.adapt} is constant. \pnum Except where specified otherwise, -no function described in this subclause~\ref{rand.adapt} +no function described in \ref{rand.adapt} throws an exception. \pnum -Every function described in this subclause~\ref{rand.adapt} +Every function described in \ref{rand.adapt} that has a function parameter \tcode{q} of type \tcode{Sseq\&} for a template type parameter named \tcode{Sseq} that is different from type \tcode{seed_seq} throws what and when the invocation of \tcode{q.generate} throws. \pnum -Descriptions are provided in this subclause~\ref{rand.adapt} +Descriptions are provided in \ref{rand.adapt} only for adaptor operations that are not described in subclause~\ref{rand.req.adapt} or for operations where there is additional semantic information. @@ -3112,9 +3428,9 @@ are not shown in the synopses. \pnum -Each template specified in this subclause~\ref{rand.adapt} +Each template specified in \ref{rand.adapt} requires one or more relationships, -involving the value(s) of its non-type template parameter(s), to hold. +involving the value(s) of its constant template parameter(s), to hold. A program instantiating any of these templates is ill-formed if any such required relationship fails to hold. @@ -3193,10 +3509,10 @@ // inserters and extractors template friend basic_ostream& - operator<<(basic_ostream& os, const discard_block_engine& x); + operator<<(basic_ostream& os, const discard_block_engine& x); // hosted template friend basic_istream& - operator>>(basic_istream& is, discard_block_engine& x); + operator>>(basic_istream& is, discard_block_engine& x); // hosted private: Engine e; // \expos @@ -3342,10 +3658,10 @@ // inserters and extractors template friend basic_ostream& - operator<<(basic_ostream& os, const independent_bits_engine& x); + operator<<(basic_ostream& os, const independent_bits_engine& x); // hosted template friend basic_istream& - operator>>(basic_istream& is, independent_bits_engine& x); + operator>>(basic_istream& is, independent_bits_engine& x); // hosted private: Engine e; // \expos @@ -3477,7 +3793,7 @@ each constructor% \indexlibraryctor{shuffle_order_engine} that is not a copy constructor -initializes $\tcode{V[0]}, \dotsc, \tcode{V[k-1]}$ and $Y$, +initializes $\tcode{V[0]}, \dotsc, \tcode{V[k - 1]}$ and $Y$, in that order, with values returned by successive invocations of \tcode{e()}.% \indextext{random number generation!engines|)} @@ -3662,6 +3978,36 @@ need not generate identical sequences across implementations. \end{note} \end{itemdescr}% + +\indexlibraryglobal{philox4x32}% +\begin{itemdecl} +using philox4x32 = + philox_engine; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\required +The $10000^\text{th}$ consecutive invocation +a default-constructed object of type \tcode{philox4x32} +produces the value $1955073260$. +\end{itemdescr}% + +\indexlibraryglobal{philox4x64}% +\begin{itemdecl} +using philox4x64 = + philox_engine; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\required +The $10000^\text{th}$ consecutive invocation +a default-constructed object of type \tcode{philox4x64} +produces the value $3409172418970261260$. +\end{itemdescr}% \indextext{random number generation!predefined engines and adaptors|)}% \indextext{random number engine adaptor!with predefined parameters|)}% \indextext{random number engine!with predefined parameters|)} @@ -4074,11 +4420,10 @@ \end{itemize} An \defn{attempt} is $k$ invocations of \tcode{g()} to obtain values $g_0, \dotsc, g_{k-1}$, respectively, -and the calculation of a quantity - \[ - S = \sum_{i=0}^{k-1} (g_i - \tcode{g.min()}) - \cdot R^i - \] +and the calculation of a quantity $S$ given by \eqref{rand.gencanonical}: +\begin{formula}{rand.gencanonical} +S = \sum_{i=0}^{k-1} (g_i - \tcode{g.min()}) \cdot R^i +\end{formula} \pnum \effects @@ -4138,16 +4483,16 @@ \rSec2[rand.dist]{Random number distribution class templates}% \indextext{random number generation!distributions|(} -\rSec3[rand.dist.general]{In general} +\rSec3[rand.dist.general]{General} \pnum Each type instantiated -from a class template specified in this subclause~\ref{rand.dist} +from a class template specified in \ref{rand.dist} meets the requirements of a random number distribution\iref{rand.req.dist} type. \pnum -Descriptions are provided in this subclause~\ref{rand.dist} +Descriptions are provided in \ref{rand.dist} only for distribution operations that are not described in \ref{rand.req.dist} or for operations where there is additional semantic information. @@ -4191,8 +4536,11 @@ produces random integers $i$, $a \leq i \leq b$, distributed according to -the constant discrete probability function% -\[ P(i\,|\,a,b) = 1 / (b - a + 1) \text{ .} \] +the constant discrete probability function in \eqref{rand.dist.uni.int}. + +\begin{formula}{rand.dist.uni.int} +P(i\,|\,a,b) = 1 / (b - a + 1) +\end{formula} \indexlibraryglobal{uniform_int_distribution}% \indexlibrarymember{result_type}{uniform_int_distribution}% @@ -4231,10 +4579,12 @@ // inserters and extractors template friend basic_ostream& - operator<<(basic_ostream& os, const uniform_int_distribution& x); + operator<<(basic_ostream& os, // hosted + const uniform_int_distribution& x); template friend basic_istream& - operator>>(basic_istream& is, uniform_int_distribution& x); + operator>>(basic_istream& is, // hosted + uniform_int_distribution& x); }; } \end{codeblock} @@ -4291,8 +4641,10 @@ produces random numbers $x$, $a \leq x < b$, distributed according to -the constant probability density function% -\[ p(x\,|\,a,b) = 1 / (b - a) \text{ .} \] +the constant probability density function in \eqref{rand.dist.uni.real}. +\begin{formula}{rand.dist.uni.real} +p(x\,|\,a,b) = 1 / (b - a) +\end{formula} \begin{note} This implies that $p(x\,|\,a,b)$ is undefined when \tcode{a == b}. \end{note} @@ -4409,12 +4761,13 @@ A \tcode{bernoulli_distribution} random number distribution produces \tcode{bool} values $b$ distributed according to -the discrete probability function -\[ P(b\,|\,p) = \left\{ \begin{array}{ll} - p & \text{ if $b = \tcode{true}$, or} \\ - 1 - p & \text{ if $b = \tcode{false}$.} +the discrete probability function in \eqref{rand.dist.bern.bernoulli}. +\begin{formula}{rand.dist.bern.bernoulli} +P(b\,|\,p) = \left\{ \begin{array}{ll} + p & \text{ if $b = \tcode{true}$} \\ + 1 - p & \text{ if $b = \tcode{false}$} \end{array}\right. -\] +\end{formula} \indexlibraryglobal{bernoulli_distribution}% \indexlibrarymember{result_type}{bernoulli_distribution}% @@ -4498,8 +4851,11 @@ A \tcode{binomial_distribution} random number distribution produces integer values $i \geq 0$ distributed according to -the discrete probability function% -\[ P(i\,|\,t,p) = \binom{t}{i} \cdot p^i \cdot (1-p)^{t-i} \text{ .} \] +the discrete probability function in \eqref{rand.dist.bern.bin}. + +\begin{formula}{rand.dist.bern.bin} +P(i\,|\,t,p) = \binom{t}{i} \cdot p^i \cdot (1-p)^{t-i} +\end{formula} \indexlibraryglobal{binomial_distribution}% \indexlibrarymember{result_type}{binomial_distribution}% @@ -4596,8 +4952,10 @@ A \tcode{geometric_distribution} random number distribution produces integer values $i \geq 0$ distributed according to -the discrete probability function -\[ P(i\,|\,p) = p \cdot (1-p)^{i} \text{ .} \] +the discrete probability function in \eqref{rand.dist.bern.geo}. +\begin{formula}{rand.dist.bern.geo} +P(i\,|\,p) = p \cdot (1-p)^{i} +\end{formula} \indexlibraryglobal{geometric_distribution}% \indexlibrarymember{result_type}{geometric_distribution}% @@ -4683,8 +5041,10 @@ A \tcode{negative_binomial_distribution} random number distribution produces random integers $i \geq 0$ distributed according to -the discrete probability function -\[ P(i\,|\,k,p) = \binom{k+i-1}{i} \cdot p^k \cdot (1-p)^i \text{ .} \] +the discrete probability function in \eqref{rand.dist.bern.negbin}. +\begin{formula}{rand.dist.bern.negbin} +P(i\,|\,k,p) = \binom{k+i-1}{i} \cdot p^k \cdot (1-p)^i +\end{formula} \begin{note} This implies that $P(i\,|\,k,p)$ is undefined when \tcode{p == 1}. \end{note} @@ -4800,11 +5160,12 @@ A \tcode{poisson_distribution} random number distribution produces integer values $i \geq 0$ distributed according to -the discrete probability function -\[ P(i\,|\,\mu) = \frac{e^{-\mu} \mu^{i}}{i\,!} \text{ .} \] +the discrete probability function in \eqref{rand.dist.pois.poisson}. +\begin{formula}{rand.dist.pois.poisson} +P(i\,|\,\mu) = \frac{e^{-\mu} \mu^{i}}{i\,!} +\end{formula} The distribution parameter $\mu$ -is also known as this distribution's \term{mean}% -. +is also known as this distribution's \term{mean}. \indexlibraryglobal{poisson_distribution}% \indexlibrarymember{result_type}{poisson_distribution}% @@ -4887,8 +5248,10 @@ An \tcode{exponential_distribution} random number distribution produces random numbers $x > 0$ distributed according to -the probability density function% -\[ p(x\,|\,\lambda) = \lambda e^{-\lambda x} \text{ .} \] +the probability density function in \eqref{rand.dist.pois.exp}. +\begin{formula}{rand.dist.pois.exp} +p(x\,|\,\lambda) = \lambda e^{-\lambda x} +\end{formula} \indexlibraryglobal{exponential_distribution}% \indexlibrarymember{result_type}{exponential_distribution}% @@ -4972,10 +5335,11 @@ A \tcode{gamma_distribution} random number distribution produces random numbers $x > 0$ distributed according to -the probability density function% -\[ p(x\,|\,\alpha,\beta) = +the probability density function in \eqref{rand.dist.pois.gamma}. +\begin{formula}{rand.dist.pois.gamma} +p(x\,|\,\alpha,\beta) = \frac{e^{-x/\beta}}{\beta^{\alpha} \cdot \Gamma(\alpha)} \, \cdot \, x^{\, \alpha-1} - \text{ .} \] +\end{formula} \indexlibraryglobal{gamma_distribution}% \indexlibrarymember{result_type}{gamma_distribution}% @@ -5074,11 +5438,12 @@ A \tcode{weibull_distribution} random number distribution produces random numbers $x \geq 0$ distributed according to -the probability density function% -\[ p(x\,|\,a,b) = \frac{a}{b} +the probability density function in \eqref{rand.dist.pois.weibull}. +\begin{formula}{rand.dist.pois.weibull} +p(x\,|\,a,b) = \frac{a}{b} \cdot \left(\frac{x}{b}\right)^{a-1} \cdot \, \exp\left( -\left(\frac{x}{b}\right)^a\right) - \text{ .} \] +\end{formula} \indexlibraryglobal{weibull_distribution}% \indexlibrarymember{result_type}{weibull_distribution}% @@ -5176,7 +5541,7 @@ An \tcode{extreme_value_distribution} random number distribution produces random numbers $x$ distributed according to -the probability density function +the probability density function in \eqref{rand.dist.pois.extreme}. \begin{footnote} The distribution corresponding to this probability density function @@ -5187,9 +5552,10 @@ or the Fisher-Tippett Type I distribution. \end{footnote} -\[ p(x\,|\,a,b) = \frac{1}{b} +\begin{formula}{rand.dist.pois.extreme} +p(x\,|\,a,b) = \frac{1}{b} \cdot \exp\left(\frac{a-x}{b} - \exp\left(\frac{a-x}{b}\right)\right) - \text{ .} \] +\end{formula} \indexlibraryglobal{extreme_value_distribution}% \indexlibrarymember{result_type}{extreme_value_distribution}% @@ -5301,8 +5667,8 @@ A \tcode{normal_distribution} random number distribution produces random numbers $x$ distributed according to -the probability density function% -\[% +the probability density function in \eqref{rand.dist.norm.normal}. +\begin{formula}{rand.dist.norm.normal} p(x\,|\,\mu,\sigma) = \frac{1}{\sigma \sqrt{2\pi}} \cdot @@ -5311,8 +5677,7 @@ {2 \sigma^2} \right) } - \text{ .} -\] +\end{formula} The distribution parameters $\mu$ and $\sigma$ are also known as this distribution's \term{mean} and \term{standard deviation}. @@ -5414,10 +5779,11 @@ A \tcode{lognormal_distribution} random number distribution produces random numbers $x > 0$ distributed according to -the probability density function% -\[ p(x\,|\,m,s) = \frac{1}{s x \sqrt{2 \pi}} +the probability density function in \eqref{rand.dist.norm.lognormal}. +\begin{formula}{rand.dist.norm.lognormal} +p(x\,|\,m,s) = \frac{1}{s x \sqrt{2 \pi}} \cdot \exp{\left(-\frac{(\ln{x} - m)^2}{2 s^2}\right)} - \text{ .} \] +\end{formula} \indexlibraryglobal{lognormal_distribution}% \indexlibrarymember{result_type}{lognormal_distribution}% @@ -5516,8 +5882,10 @@ A \tcode{chi_squared_distribution} random number distribution produces random numbers $x > 0$ distributed according to -the probability density function% -\[ p(x\,|\,n) = \frac{x^{(n/2)-1} \cdot e^{-x/2}}{\Gamma(n/2) \cdot 2^{n/2}} \text{ .} \] +the probability density function in \eqref{rand.dist.norm.chisq}. +\begin{formula}{rand.dist.norm.chisq} +p(x\,|\,n) = \frac{x^{(n/2)-1} \cdot e^{-x/2}}{\Gamma(n/2) \cdot 2^{n/2}} +\end{formula} \indexlibraryglobal{chi_squared_distribution}% \indexlibrarymember{result_type}{chi_squared_distribution}% @@ -5602,8 +5970,10 @@ A \tcode{cauchy_distribution} random number distribution produces random numbers $x$ distributed according to -the probability density function% -\[ p(x\,|\,a,b) = \left(\pi b \left(1 + \left(\frac{x-a}{b} \right)^2 \, \right)\right)^{-1} \text{ .} \] +the probability density function in \eqref{rand.dist.norm.cauchy}. +\begin{formula}{rand.dist.norm.cauchy} +p(x\,|\,a,b) = \left(\pi b \left(1 + \left(\frac{x-a}{b} \right)^2 \, \right)\right)^{-1} +\end{formula} \indexlibraryglobal{cauchy_distribution}% \indexlibrarymember{result_type}{cauchy_distribution}% @@ -5702,12 +6072,13 @@ A \tcode{fisher_f_distribution} random number distribution produces random numbers $x \ge 0$ distributed according to -the probability density function% -\[ p(x\,|\,m,n) = \frac{\Gamma\big((m+n)/2\big)}{\Gamma(m/2) \; \Gamma(n/2)} +the probability density function in \eqref{rand.dist.norm.f}. +\begin{formula}{rand.dist.norm.f} +p(x\,|\,m,n) = \frac{\Gamma\big((m+n)/2\big)}{\Gamma(m/2) \; \Gamma(n/2)} \cdot \left(\frac{m}{n}\right)^{m/2} \cdot x^{(m/2)-1} \cdot \left(1 + \frac{m x}{n}\right)^{-(m + n)/2} - \text{ .} \] +\end{formula} \indexlibraryglobal{fisher_f_distribution}% \indexlibrarymember{result_type}{fisher_distribution}% @@ -5806,11 +6177,12 @@ A \tcode{student_t_distribution} random number distribution produces random numbers $x$ distributed according to -the probability density function% -\[ p(x\,|\,n) = \frac{1}{\sqrt{n \pi}} +the probability density function in \eqref{rand.dist.norm.t}. +\begin{formula}{rand.dist.norm.t} +p(x\,|\,n) = \frac{1}{\sqrt{n \pi}} \cdot \frac{\Gamma\big((n+1)/2\big)}{\Gamma(n/2)} \cdot \left(1 + \frac{x^2}{n} \right)^{-(n+1)/2} - \text{ .} \] +\end{formula} \indexlibraryglobal{student_t_distribution}% \indexlibrarymember{result_type}{student_t_distribution}% @@ -5909,8 +6281,10 @@ A \tcode{discrete_distribution} random number distribution produces random integers $i$, $0 \leq i < n$, distributed according to -the discrete probability function% -\[ P(i \,|\, p_0, \dotsc, p_{n-1}) = p_i \text{ .} \] +the discrete probability function in \eqref{rand.dist.samp.discrete}. +\begin{formula}{rand.dist.samp.discrete} +P(i \,|\, p_0, \dotsc, p_{n-1}) = p_i +\end{formula} \pnum Unless specified otherwise, @@ -6011,7 +6385,7 @@ \pnum \effects Constructs a \tcode{discrete_distribution} object -with probabilities given by the formula above. +with probabilities given by the \eqref{rand.dist.samp.discrete}. \end{itemdescr} @@ -6088,9 +6462,11 @@ $b_0 \leq x < b_n$, uniformly distributed over each subinterval $[ b_i, b_{i+1} )$ -according to the probability density function -\[ p(x \,|\, b_0, \dotsc, b_n, \; \rho_0, \dotsc, \rho_{n-1}) = \rho_i - \text{ , for $b_i \le x < b_{i+1}$.} \] +according to the probability density function in \eqref{rand.dist.samp.pconst}. +\begin{formula}{rand.dist.samp.pconst} +p(x \,|\, b_0, \dotsc, b_n, \; \rho_0, \dotsc, \rho_{n-1}) = \rho_i + \text{ , for $b_i \le x < b_{i+1}$} +\end{formula} \pnum The $n + 1$ distribution parameters $b_i$, @@ -6179,8 +6555,8 @@ \indexlibraryctor{piecewise_constant_distribution}% \begin{itemdecl} template - piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB, - InputIteratorW firstW); + piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB, + InputIteratorW firstW); \end{itemdecl} \begin{itemdescr} @@ -6221,7 +6597,7 @@ \indexlibraryctor{piecewise_constant_distribution}% \begin{itemdecl} template - piecewise_constant_distribution(initializer_list bl, UnaryOperation fw); + piecewise_constant_distribution(initializer_list bl, UnaryOperation fw); \end{itemdecl} \begin{itemdescr} @@ -6255,7 +6631,7 @@ \indexlibraryctor{piecewise_constant_distribution}% \begin{itemdecl} template - piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw); + piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw); \end{itemdecl} \begin{itemdescr} @@ -6324,11 +6700,13 @@ $b_0 \leq x < b_n$, distributed over each subinterval $[b_i, b_{i+1})$ -according to the probability density function -\[ p(x \,|\, b_0, \dotsc, b_n, \; \rho_0, \dotsc, \rho_n) +according to the probability density function in \eqref{rand.dist.samp.plinear}. +\begin{formula}{rand.dist.samp.plinear} +p(x \,|\, b_0, \dotsc, b_n, \; \rho_0, \dotsc, \rho_n) = \rho_{i} \cdot {\frac{b_{i+1} - x}{b_{i+1} - b_i}} + \rho_{i+1} \cdot {\frac{x - b_i}{b_{i+1} - b_i}} - \text{ , for $b_i \le x < b_{i+1}$.} \] + \text{ , for $b_i \le x < b_{i+1}$.} +\end{formula} \pnum The $n + 1$ distribution parameters $b_i$, @@ -6412,8 +6790,8 @@ \indexlibraryctor{piecewise_linear_distribution} \begin{itemdecl} template - piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB, - InputIteratorW firstW); + piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB, + InputIteratorW firstW); \end{itemdecl} \begin{itemdescr} @@ -6454,7 +6832,7 @@ \indexlibraryctor{piecewise_linear_distribution}% \begin{itemdecl} template - piecewise_linear_distribution(initializer_list bl, UnaryOperation fw); + piecewise_linear_distribution(initializer_list bl, UnaryOperation fw); \end{itemdecl} \begin{itemdescr} @@ -6488,7 +6866,7 @@ \indexlibraryctor{piecewise_linear_distribution}% \begin{itemdecl} template - piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw); + piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw); \end{itemdecl} \begin{itemdescr} @@ -7197,13 +7575,13 @@ \indexlibrarymember{operator[]}{valarray}% \begin{itemdecl} -const T& operator[](size_t n) const; +const T& operator[](size_t n) const; T& operator[](size_t n); \end{itemdecl} \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{n < size()} is \tcode{true}. \pnum @@ -8826,23 +9204,6 @@ \rSec2[cmath.syn]{Header \tcode{} synopsis} \indexheader{cmath}% -\indexlibraryglobal{FP_FAST_FMA}% -\indexlibraryglobal{FP_FAST_FMAF}% -\indexlibraryglobal{FP_FAST_FMAL}% -\indexlibraryglobal{FP_ILOGB0}% -\indexlibraryglobal{FP_ILOGBNAN}% -\indexlibraryglobal{FP_INFINITE}% -\indexlibraryglobal{FP_NAN}% -\indexlibraryglobal{FP_NORMAL}% -\indexlibraryglobal{FP_SUBNORMAL}% -\indexlibraryglobal{FP_ZERO}% -\indexlibraryglobal{HUGE_VAL}% -\indexlibraryglobal{HUGE_VALF}% -\indexlibraryglobal{HUGE_VALL}% -\indexlibraryglobal{INFINITY}% -\indexlibraryglobal{MATH_ERREXCEPT}% -\indexlibraryglobal{MATH_ERRNO}% -\indexlibraryglobal{NAN}% \indexlibraryglobal{abs}% \indexlibraryglobal{acos}% \indexlibraryglobal{acosf}% @@ -8971,7 +9332,6 @@ \indexlibraryglobal{lround}% \indexlibraryglobal{lroundf}% \indexlibraryglobal{lroundl}% -\indexlibraryglobal{math_errhandling}% \indexlibraryglobal{modf}% \indexlibraryglobal{modff}% \indexlibraryglobal{modfl}% @@ -9031,398 +9391,396 @@ \indexlibraryglobal{truncf}% \indexlibraryglobal{truncl}% \begin{codeblock} +#define @\libmacro{HUGE_VAL}@ @\seebelow@ +#define @\libmacro{HUGE_VALF}@ @\seebelow@ +#define @\libmacro{HUGE_VALL}@ @\seebelow@ +#define @\libmacro{INFINITY}@ @\seebelow@ +#define @\libmacro{NAN}@ @\seebelow@ +#define @\libmacro{FP_INFINITE}@ @\seebelow@ +#define @\libmacro{FP_NAN}@ @\seebelow@ +#define @\libmacro{FP_NORMAL}@ @\seebelow@ +#define @\libmacro{FP_SUBNORMAL}@ @\seebelow@ +#define @\libmacro{FP_ZERO}@ @\seebelow@ +#define @\libmacro{FP_FAST_FMA}@ @\seebelow@ +#define @\libmacro{FP_FAST_FMAF}@ @\seebelow@ +#define @\libmacro{FP_FAST_FMAL}@ @\seebelow@ +#define @\libmacro{FP_ILOGB0}@ @\seebelow@ +#define @\libmacro{FP_ILOGBNAN}@ @\seebelow@ +#define @\libmacro{MATH_ERRNO}@ @\seebelow@ +#define @\libmacro{MATH_ERREXCEPT}@ @\seebelow@ + +#define @\libmacro{math_errhandling}@ @\seebelow@ + namespace std { using float_t = @\seebelow@; using double_t = @\seebelow@; -} - -#define HUGE_VAL @\seebelow@ -#define HUGE_VALF @\seebelow@ -#define HUGE_VALL @\seebelow@ -#define INFINITY @\seebelow@ -#define NAN @\seebelow@ -#define FP_INFINITE @\seebelow@ -#define FP_NAN @\seebelow@ -#define FP_NORMAL @\seebelow@ -#define FP_SUBNORMAL @\seebelow@ -#define FP_ZERO @\seebelow@ -#define FP_FAST_FMA @\seebelow@ -#define FP_FAST_FMAF @\seebelow@ -#define FP_FAST_FMAL @\seebelow@ -#define FP_ILOGB0 @\seebelow@ -#define FP_ILOGBNAN @\seebelow@ -#define MATH_ERRNO @\seebelow@ -#define MATH_ERREXCEPT @\seebelow@ - -#define math_errhandling @\seebelow@ -namespace std { - constexpr @\placeholder{floating-point-type}@ acos(@\placeholder{floating-point-type}@ x); - constexpr float acosf(float x); - constexpr long double acosl(long double x); + constexpr @\placeholdernc{floating-point-type}@ acos(@\placeholdernc{floating-point-type}@ x); + constexpr float acosf(float x); + constexpr long double acosl(long double x); - constexpr @\placeholder{floating-point-type}@ asin(@\placeholder{floating-point-type}@ x); - constexpr float asinf(float x); - constexpr long double asinl(long double x); + constexpr @\placeholdernc{floating-point-type}@ asin(@\placeholdernc{floating-point-type}@ x); + constexpr float asinf(float x); + constexpr long double asinl(long double x); - constexpr @\placeholder{floating-point-type}@ atan(@\placeholder{floating-point-type}@ x); - constexpr float atanf(float x); - constexpr long double atanl(long double x); + constexpr @\placeholdernc{floating-point-type}@ atan(@\placeholdernc{floating-point-type}@ x); + constexpr float atanf(float x); + constexpr long double atanl(long double x); - constexpr @\placeholder{floating-point-type}@ atan2(@\placeholder{floating-point-type}@ y, @\placeholder{floating-point-type}@ x); - constexpr float atan2f(float y, float x); - constexpr long double atan2l(long double y, long double x); + constexpr @\placeholdernc{floating-point-type}@ atan2(@\placeholdernc{floating-point-type}@ y, @\placeholdernc{floating-point-type}@ x); + constexpr float atan2f(float y, float x); + constexpr long double atan2l(long double y, long double x); - constexpr @\placeholder{floating-point-type}@ cos(@\placeholder{floating-point-type}@ x); - constexpr float cosf(float x); - constexpr long double cosl(long double x); + constexpr @\placeholdernc{floating-point-type}@ cos(@\placeholdernc{floating-point-type}@ x); + constexpr float cosf(float x); + constexpr long double cosl(long double x); - constexpr @\placeholder{floating-point-type}@ sin(@\placeholder{floating-point-type}@ x); - constexpr float sinf(float x); - constexpr long double sinl(long double x); + constexpr @\placeholdernc{floating-point-type}@ sin(@\placeholdernc{floating-point-type}@ x); + constexpr float sinf(float x); + constexpr long double sinl(long double x); - constexpr @\placeholder{floating-point-type}@ tan(@\placeholder{floating-point-type}@ x); - constexpr float tanf(float x); - constexpr long double tanl(long double x); + constexpr @\placeholdernc{floating-point-type}@ tan(@\placeholdernc{floating-point-type}@ x); + constexpr float tanf(float x); + constexpr long double tanl(long double x); - constexpr @\placeholder{floating-point-type}@ acosh(@\placeholder{floating-point-type}@ x); - constexpr float acoshf(float x); - constexpr long double acoshl(long double x); + constexpr @\placeholdernc{floating-point-type}@ acosh(@\placeholdernc{floating-point-type}@ x); + constexpr float acoshf(float x); + constexpr long double acoshl(long double x); - constexpr @\placeholder{floating-point-type}@ asinh(@\placeholder{floating-point-type}@ x); - constexpr float asinhf(float x); - constexpr long double asinhl(long double x); + constexpr @\placeholdernc{floating-point-type}@ asinh(@\placeholdernc{floating-point-type}@ x); + constexpr float asinhf(float x); + constexpr long double asinhl(long double x); - constexpr @\placeholder{floating-point-type}@ atanh(@\placeholder{floating-point-type}@ x); - constexpr float atanhf(float x); - constexpr long double atanhl(long double x); + constexpr @\placeholdernc{floating-point-type}@ atanh(@\placeholdernc{floating-point-type}@ x); + constexpr float atanhf(float x); + constexpr long double atanhl(long double x); - constexpr @\placeholder{floating-point-type}@ cosh(@\placeholder{floating-point-type}@ x); - constexpr float coshf(float x); - constexpr long double coshl(long double x); + constexpr @\placeholdernc{floating-point-type}@ cosh(@\placeholdernc{floating-point-type}@ x); + constexpr float coshf(float x); + constexpr long double coshl(long double x); - constexpr @\placeholder{floating-point-type}@ sinh(@\placeholder{floating-point-type}@ x); - constexpr float sinhf(float x); - constexpr long double sinhl(long double x); + constexpr @\placeholdernc{floating-point-type}@ sinh(@\placeholdernc{floating-point-type}@ x); + constexpr float sinhf(float x); + constexpr long double sinhl(long double x); - constexpr @\placeholder{floating-point-type}@ tanh(@\placeholder{floating-point-type}@ x); - constexpr float tanhf(float x); - constexpr long double tanhl(long double x); + constexpr @\placeholdernc{floating-point-type}@ tanh(@\placeholdernc{floating-point-type}@ x); + constexpr float tanhf(float x); + constexpr long double tanhl(long double x); - constexpr @\placeholder{floating-point-type}@ exp(@\placeholder{floating-point-type}@ x); - constexpr float expf(float x); - constexpr long double expl(long double x); + constexpr @\placeholdernc{floating-point-type}@ exp(@\placeholdernc{floating-point-type}@ x); + constexpr float expf(float x); + constexpr long double expl(long double x); - constexpr @\placeholder{floating-point-type}@ exp2(@\placeholder{floating-point-type}@ x); - constexpr float exp2f(float x); - constexpr long double exp2l(long double x); + constexpr @\placeholdernc{floating-point-type}@ exp2(@\placeholdernc{floating-point-type}@ x); + constexpr float exp2f(float x); + constexpr long double exp2l(long double x); - constexpr @\placeholder{floating-point-type}@ expm1(@\placeholder{floating-point-type}@ x); - constexpr float expm1f(float x); - constexpr long double expm1l(long double x); + constexpr @\placeholdernc{floating-point-type}@ expm1(@\placeholdernc{floating-point-type}@ x); + constexpr float expm1f(float x); + constexpr long double expm1l(long double x); - constexpr @\placeholder{floating-point-type}@ frexp(@\placeholder{floating-point-type}@ value, int* exp); - constexpr float frexpf(float value, int* exp); - constexpr long double frexpl(long double value, int* exp); + constexpr @\placeholdernc{floating-point-type}@ frexp(@\placeholdernc{floating-point-type}@ value, int* exp); + constexpr float frexpf(float value, int* exp); + constexpr long double frexpl(long double value, int* exp); - constexpr int ilogb(@\placeholder{floating-point-type}@ x); + constexpr int ilogb(@\placeholdernc{floating-point-type}@ x); constexpr int ilogbf(float x); constexpr int ilogbl(long double x); - constexpr @\placeholder{floating-point-type}@ ldexp(@\placeholder{floating-point-type}@ x, int exp); - constexpr float ldexpf(float x, int exp); - constexpr long double ldexpl(long double x, int exp); + constexpr @\placeholdernc{floating-point-type}@ ldexp(@\placeholdernc{floating-point-type}@ x, int exp); + constexpr float ldexpf(float x, int exp); + constexpr long double ldexpl(long double x, int exp); - constexpr @\placeholder{floating-point-type}@ log(@\placeholder{floating-point-type}@ x); - constexpr float logf(float x); - constexpr long double logl(long double x); + constexpr @\placeholdernc{floating-point-type}@ log(@\placeholdernc{floating-point-type}@ x); + constexpr float logf(float x); + constexpr long double logl(long double x); - constexpr @\placeholder{floating-point-type}@ log10(@\placeholder{floating-point-type}@ x); - constexpr float log10f(float x); - constexpr long double log10l(long double x); + constexpr @\placeholdernc{floating-point-type}@ log10(@\placeholdernc{floating-point-type}@ x); + constexpr float log10f(float x); + constexpr long double log10l(long double x); - constexpr @\placeholder{floating-point-type}@ log1p(@\placeholder{floating-point-type}@ x); - constexpr float log1pf(float x); - constexpr long double log1pl(long double x); + constexpr @\placeholdernc{floating-point-type}@ log1p(@\placeholdernc{floating-point-type}@ x); + constexpr float log1pf(float x); + constexpr long double log1pl(long double x); - constexpr @\placeholder{floating-point-type}@ log2(@\placeholder{floating-point-type}@ x); - constexpr float log2f(float x); - constexpr long double log2l(long double x); + constexpr @\placeholdernc{floating-point-type}@ log2(@\placeholdernc{floating-point-type}@ x); + constexpr float log2f(float x); + constexpr long double log2l(long double x); - constexpr @\placeholder{floating-point-type}@ logb(@\placeholder{floating-point-type}@ x); - constexpr float logbf(float x); - constexpr long double logbl(long double x); + constexpr @\placeholdernc{floating-point-type}@ logb(@\placeholdernc{floating-point-type}@ x); + constexpr float logbf(float x); + constexpr long double logbl(long double x); - constexpr @\placeholder{floating-point-type}@ modf(@\placeholder{floating-point-type}@ value, @\placeholder{floating-point-type}@* iptr); - constexpr float modff(float value, float* iptr); - constexpr long double modfl(long double value, long double* iptr); + constexpr @\placeholdernc{floating-point-type}@ modf(@\placeholdernc{floating-point-type}@ value, @\placeholdernc{floating-point-type}@* iptr); + constexpr float modff(float value, float* iptr); + constexpr long double modfl(long double value, long double* iptr); - constexpr @\placeholder{floating-point-type}@ scalbn(@\placeholder{floating-point-type}@ x, int n); - constexpr float scalbnf(float x, int n); - constexpr long double scalbnl(long double x, int n); + constexpr @\placeholdernc{floating-point-type}@ scalbn(@\placeholdernc{floating-point-type}@ x, int n); + constexpr float scalbnf(float x, int n); + constexpr long double scalbnl(long double x, int n); - constexpr @\placeholder{floating-point-type}@ scalbln(@\placeholder{floating-point-type}@ x, long int n); - constexpr float scalblnf(float x, long int n); - constexpr long double scalblnl(long double x, long int n); + constexpr @\placeholdernc{floating-point-type}@ scalbln(@\placeholdernc{floating-point-type}@ x, long int n); + constexpr float scalblnf(float x, long int n); + constexpr long double scalblnl(long double x, long int n); - constexpr @\placeholder{floating-point-type}@ cbrt(@\placeholder{floating-point-type}@ x); - constexpr float cbrtf(float x); - constexpr long double cbrtl(long double x); + constexpr @\placeholdernc{floating-point-type}@ cbrt(@\placeholdernc{floating-point-type}@ x); + constexpr float cbrtf(float x); + constexpr long double cbrtl(long double x); // \ref{c.math.abs}, absolute values - constexpr int abs(int j); // freestanding - constexpr long int abs(long int j); // freestanding - constexpr long long int abs(long long int j); // freestanding - constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j); // freestanding-deleted + constexpr int abs(int j); // freestanding + constexpr long int abs(long int j); // freestanding + constexpr long long int abs(long long int j); // freestanding + constexpr @\placeholdernc{floating-point-type}@ abs(@\placeholdernc{floating-point-type}@ j); // freestanding-deleted - constexpr @\placeholder{floating-point-type}@ fabs(@\placeholder{floating-point-type}@ x); - constexpr float fabsf(float x); - constexpr long double fabsl(long double x); + constexpr @\placeholdernc{floating-point-type}@ fabs(@\placeholdernc{floating-point-type}@ x); + constexpr float fabsf(float x); + constexpr long double fabsl(long double x); - constexpr @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float hypotf(float x, float y); - constexpr long double hypotl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ hypot(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float hypotf(float x, float y); + constexpr long double hypotl(long double x, long double y); // \ref{c.math.hypot3}, three-dimensional hypotenuse - constexpr @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, - @\placeholder{floating-point-type}@ z); + constexpr @\placeholdernc{floating-point-type}@ hypot(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y, + @\placeholdernc{floating-point-type}@ z); - constexpr @\placeholder{floating-point-type}@ pow(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float powf(float x, float y); - constexpr long double powl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ pow(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float powf(float x, float y); + constexpr long double powl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ sqrt(@\placeholder{floating-point-type}@ x); - constexpr float sqrtf(float x); - constexpr long double sqrtl(long double x); + constexpr @\placeholdernc{floating-point-type}@ sqrt(@\placeholdernc{floating-point-type}@ x); + constexpr float sqrtf(float x); + constexpr long double sqrtl(long double x); - constexpr @\placeholder{floating-point-type}@ erf(@\placeholder{floating-point-type}@ x); - constexpr float erff(float x); - constexpr long double erfl(long double x); + constexpr @\placeholdernc{floating-point-type}@ erf(@\placeholdernc{floating-point-type}@ x); + constexpr float erff(float x); + constexpr long double erfl(long double x); - constexpr @\placeholder{floating-point-type}@ erfc(@\placeholder{floating-point-type}@ x); - constexpr float erfcf(float x); - constexpr long double erfcl(long double x); + constexpr @\placeholdernc{floating-point-type}@ erfc(@\placeholdernc{floating-point-type}@ x); + constexpr float erfcf(float x); + constexpr long double erfcl(long double x); - constexpr @\placeholder{floating-point-type}@ lgamma(@\placeholder{floating-point-type}@ x); - constexpr float lgammaf(float x); - constexpr long double lgammal(long double x); + constexpr @\placeholdernc{floating-point-type}@ lgamma(@\placeholdernc{floating-point-type}@ x); + constexpr float lgammaf(float x); + constexpr long double lgammal(long double x); - constexpr @\placeholder{floating-point-type}@ tgamma(@\placeholder{floating-point-type}@ x); - constexpr float tgammaf(float x); - constexpr long double tgammal(long double x); + constexpr @\placeholdernc{floating-point-type}@ tgamma(@\placeholdernc{floating-point-type}@ x); + constexpr float tgammaf(float x); + constexpr long double tgammal(long double x); - constexpr @\placeholder{floating-point-type}@ ceil(@\placeholder{floating-point-type}@ x); - constexpr float ceilf(float x); - constexpr long double ceill(long double x); + constexpr @\placeholdernc{floating-point-type}@ ceil(@\placeholdernc{floating-point-type}@ x); + constexpr float ceilf(float x); + constexpr long double ceill(long double x); - constexpr @\placeholder{floating-point-type}@ floor(@\placeholder{floating-point-type}@ x); - constexpr float floorf(float x); - constexpr long double floorl(long double x); + constexpr @\placeholdernc{floating-point-type}@ floor(@\placeholdernc{floating-point-type}@ x); + constexpr float floorf(float x); + constexpr long double floorl(long double x); - @\placeholder{floating-point-type}@ nearbyint(@\placeholder{floating-point-type}@ x); - float nearbyintf(float x); - long double nearbyintl(long double x); + @\placeholdernc{floating-point-type}@ nearbyint(@\placeholdernc{floating-point-type}@ x); + float nearbyintf(float x); + long double nearbyintl(long double x); - @\placeholder{floating-point-type}@ rint(@\placeholder{floating-point-type}@ x); - float rintf(float x); - long double rintl(long double x); + @\placeholdernc{floating-point-type}@ rint(@\placeholdernc{floating-point-type}@ x); + float rintf(float x); + long double rintl(long double x); - long int lrint(@\placeholder{floating-point-type}@ x); + long int lrint(@\placeholdernc{floating-point-type}@ x); long int lrintf(float x); long int lrintl(long double x); - long long int llrint(@\placeholder{floating-point-type}@ x); + long long int llrint(@\placeholdernc{floating-point-type}@ x); long long int llrintf(float x); long long int llrintl(long double x); - constexpr @\placeholder{floating-point-type}@ round(@\placeholder{floating-point-type}@ x); - constexpr float roundf(float x); - constexpr long double roundl(long double x); + constexpr @\placeholdernc{floating-point-type}@ round(@\placeholdernc{floating-point-type}@ x); + constexpr float roundf(float x); + constexpr long double roundl(long double x); - constexpr long int lround(@\placeholder{floating-point-type}@ x); + constexpr long int lround(@\placeholdernc{floating-point-type}@ x); constexpr long int lroundf(float x); constexpr long int lroundl(long double x); - constexpr long long int llround(@\placeholder{floating-point-type}@ x); + constexpr long long int llround(@\placeholdernc{floating-point-type}@ x); constexpr long long int llroundf(float x); constexpr long long int llroundl(long double x); - constexpr @\placeholder{floating-point-type}@ trunc(@\placeholder{floating-point-type}@ x); - constexpr float truncf(float x); - constexpr long double truncl(long double x); + constexpr @\placeholdernc{floating-point-type}@ trunc(@\placeholdernc{floating-point-type}@ x); + constexpr float truncf(float x); + constexpr long double truncl(long double x); - constexpr @\placeholder{floating-point-type}@ fmod(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float fmodf(float x, float y); - constexpr long double fmodl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ fmod(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float fmodf(float x, float y); + constexpr long double fmodl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ remainder(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float remainderf(float x, float y); - constexpr long double remainderl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ remainder(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float remainderf(float x, float y); + constexpr long double remainderl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ remquo(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, int* quo); - constexpr float remquof(float x, float y, int* quo); - constexpr long double remquol(long double x, long double y, int* quo); + constexpr @\placeholdernc{floating-point-type}@ remquo(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y, int* quo); + constexpr float remquof(float x, float y, int* quo); + constexpr long double remquol(long double x, long double y, int* quo); - constexpr @\placeholder{floating-point-type}@ copysign(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float copysignf(float x, float y); - constexpr long double copysignl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ copysign(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float copysignf(float x, float y); + constexpr long double copysignl(long double x, long double y); - double nan(const char* tagp); - float nanf(const char* tagp); + double nan(const char* tagp); + float nanf(const char* tagp); long double nanl(const char* tagp); - constexpr @\placeholder{floating-point-type}@ nextafter(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float nextafterf(float x, float y); - constexpr long double nextafterl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ nextafter(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float nextafterf(float x, float y); + constexpr long double nextafterl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ nexttoward(@\placeholder{floating-point-type}@ x, long double y); - constexpr float nexttowardf(float x, long double y); - constexpr long double nexttowardl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ nexttoward(@\placeholdernc{floating-point-type}@ x, long double y); + constexpr float nexttowardf(float x, long double y); + constexpr long double nexttowardl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ fdim(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float fdimf(float x, float y); - constexpr long double fdiml(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ fdim(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float fdimf(float x, float y); + constexpr long double fdiml(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ fmax(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float fmaxf(float x, float y); - constexpr long double fmaxl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ fmax(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float fmaxf(float x, float y); + constexpr long double fmaxl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ fmin(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr float fminf(float x, float y); - constexpr long double fminl(long double x, long double y); + constexpr @\placeholdernc{floating-point-type}@ fmin(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr float fminf(float x, float y); + constexpr long double fminl(long double x, long double y); - constexpr @\placeholder{floating-point-type}@ fma(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, - @\placeholder{floating-point-type}@ z); - constexpr float fmaf(float x, float y, float z); - constexpr long double fmal(long double x, long double y, long double z); + constexpr @\placeholdernc{floating-point-type}@ fma(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y, + @\placeholdernc{floating-point-type}@ z); + constexpr float fmaf(float x, float y, float z); + constexpr long double fmal(long double x, long double y, long double z); // \ref{c.math.lerp}, linear interpolation - constexpr @\placeholder{floating-point-type}@ lerp(@\placeholder{floating-point-type}@ a, @\placeholder{floating-point-type}@ b, - @\placeholder{floating-point-type}@ t) noexcept; + constexpr @\placeholdernc{floating-point-type}@ lerp(@\placeholdernc{floating-point-type}@ a, @\placeholdernc{floating-point-type}@ b, + @\placeholdernc{floating-point-type}@ t) noexcept; // \ref{c.math.fpclass}, classification / comparison functions - constexpr int fpclassify(@\placeholder{floating-point-type}@ x); - constexpr bool isfinite(@\placeholder{floating-point-type}@ x); - constexpr bool isinf(@\placeholder{floating-point-type}@ x); - constexpr bool isnan(@\placeholder{floating-point-type}@ x); - constexpr bool isnormal(@\placeholder{floating-point-type}@ x); - constexpr bool signbit(@\placeholder{floating-point-type}@ x); - constexpr bool isgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr bool isgreaterequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr bool isless(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr bool islessequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr bool islessgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - constexpr bool isunordered(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr int fpclassify(@\placeholdernc{floating-point-type}@ x); + constexpr bool isfinite(@\placeholdernc{floating-point-type}@ x); + constexpr bool isinf(@\placeholdernc{floating-point-type}@ x); + constexpr bool isnan(@\placeholdernc{floating-point-type}@ x); + constexpr bool isnormal(@\placeholdernc{floating-point-type}@ x); + constexpr bool signbit(@\placeholdernc{floating-point-type}@ x); + constexpr bool isgreater(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr bool isgreaterequal(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr bool isless(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr bool islessequal(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr bool islessgreater(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + constexpr bool isunordered(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); // \ref{sf.cmath}, mathematical special functions // \ref{sf.cmath.assoc.laguerre}, associated Laguerre polynomials - @\placeholder{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholder{floating-point-type}@ x); - float assoc_laguerref(unsigned n, unsigned m, float x); - long double assoc_laguerrel(unsigned n, unsigned m, long double x); + @\placeholdernc{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholdernc{floating-point-type}@ x); + float assoc_laguerref(unsigned n, unsigned m, float x); + long double assoc_laguerrel(unsigned n, unsigned m, long double x); // \ref{sf.cmath.assoc.legendre}, associated Legendre functions - @\placeholder{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ x); - float assoc_legendref(unsigned l, unsigned m, float x); - long double assoc_legendrel(unsigned l, unsigned m, long double x); + @\placeholdernc{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholdernc{floating-point-type}@ x); + float assoc_legendref(unsigned l, unsigned m, float x); + long double assoc_legendrel(unsigned l, unsigned m, long double x); // \ref{sf.cmath.beta}, beta function - @\placeholder{floating-point-type}@ beta(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); - float betaf(float x, float y); - long double betal(long double x, long double y); + @\placeholdernc{floating-point-type}@ beta(@\placeholdernc{floating-point-type}@ x, @\placeholdernc{floating-point-type}@ y); + float betaf(float x, float y); + long double betal(long double x, long double y); // \ref{sf.cmath.comp.ellint.1}, complete elliptic integral of the first kind - @\placeholder{floating-point-type}@ comp_ellint_1(@\placeholder{floating-point-type}@ k); - float comp_ellint_1f(float k); - long double comp_ellint_1l(long double k); + @\placeholdernc{floating-point-type}@ comp_ellint_1(@\placeholdernc{floating-point-type}@ k); + float comp_ellint_1f(float k); + long double comp_ellint_1l(long double k); // \ref{sf.cmath.comp.ellint.2}, complete elliptic integral of the second kind - @\placeholder{floating-point-type}@ comp_ellint_2(@\placeholder{floating-point-type}@ k); - float comp_ellint_2f(float k); - long double comp_ellint_2l(long double k); + @\placeholdernc{floating-point-type}@ comp_ellint_2(@\placeholdernc{floating-point-type}@ k); + float comp_ellint_2f(float k); + long double comp_ellint_2l(long double k); // \ref{sf.cmath.comp.ellint.3}, complete elliptic integral of the third kind - @\placeholder{floating-point-type}@ comp_ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu); - float comp_ellint_3f(float k, float nu); - long double comp_ellint_3l(long double k, long double nu); + @\placeholdernc{floating-point-type}@ comp_ellint_3(@\placeholdernc{floating-point-type}@ k, @\placeholdernc{floating-point-type}@ nu); + float comp_ellint_3f(float k, float nu); + long double comp_ellint_3l(long double k, long double nu); // \ref{sf.cmath.cyl.bessel.i}, regular modified cylindrical Bessel functions - @\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); - long double cyl_bessel_il(long double nu, long double x); + @\placeholdernc{floating-point-type}@ cyl_bessel_i(@\placeholdernc{floating-point-type}@ nu, @\placeholdernc{floating-point-type}@ x); + float cyl_bessel_if(float nu, float x); + long double cyl_bessel_il(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.j}, cylindrical Bessel functions of the first kind - @\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); - long double cyl_bessel_jl(long double nu, long double x); + @\placeholdernc{floating-point-type}@ cyl_bessel_j(@\placeholdernc{floating-point-type}@ nu, @\placeholdernc{floating-point-type}@ x); + float cyl_bessel_jf(float nu, float x); + long double cyl_bessel_jl(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.k}, irregular modified cylindrical Bessel functions - @\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); - long double cyl_bessel_kl(long double nu, long double x); + @\placeholdernc{floating-point-type}@ cyl_bessel_k(@\placeholdernc{floating-point-type}@ nu, @\placeholdernc{floating-point-type}@ x); + float cyl_bessel_kf(float nu, float x); + long double cyl_bessel_kl(long double nu, long double x); // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions // cylindrical Bessel functions of the second kind - @\placeholder{floating-point-type}@ cyl_neumann(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); - float cyl_neumannf(float nu, float x); - long double cyl_neumannl(long double nu, long double x); + @\placeholdernc{floating-point-type}@ cyl_neumann(@\placeholdernc{floating-point-type}@ nu, @\placeholdernc{floating-point-type}@ x); + float cyl_neumannf(float nu, float x); + long double cyl_neumannl(long double nu, long double x); // \ref{sf.cmath.ellint.1}, incomplete elliptic integral of the first kind - @\placeholder{floating-point-type}@ ellint_1(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); - float ellint_1f(float k, float phi); - long double ellint_1l(long double k, long double phi); + @\placeholdernc{floating-point-type}@ ellint_1(@\placeholdernc{floating-point-type}@ k, @\placeholdernc{floating-point-type}@ phi); + float ellint_1f(float k, float phi); + long double ellint_1l(long double k, long double phi); // \ref{sf.cmath.ellint.2}, incomplete elliptic integral of the second kind - @\placeholder{floating-point-type}@ ellint_2(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); - float ellint_2f(float k, float phi); - long double ellint_2l(long double k, long double phi); + @\placeholdernc{floating-point-type}@ ellint_2(@\placeholdernc{floating-point-type}@ k, @\placeholdernc{floating-point-type}@ phi); + float ellint_2f(float k, float phi); + long double ellint_2l(long double k, long double phi); // \ref{sf.cmath.ellint.3}, incomplete elliptic integral of the third kind - @\placeholder{floating-point-type}@ ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu, - @\placeholder{floating-point-type}@ phi); - float ellint_3f(float k, float nu, float phi); - long double ellint_3l(long double k, long double nu, long double phi); + @\placeholdernc{floating-point-type}@ ellint_3(@\placeholdernc{floating-point-type}@ k, @\placeholdernc{floating-point-type}@ nu, + @\placeholdernc{floating-point-type}@ phi); + float ellint_3f(float k, float nu, float phi); + long double ellint_3l(long double k, long double nu, long double phi); // \ref{sf.cmath.expint}, exponential integral - @\placeholder{floating-point-type}@ expint(@\placeholder{floating-point-type}@ x); - float expintf(float x); - long double expintl(long double x); + @\placeholdernc{floating-point-type}@ expint(@\placeholdernc{floating-point-type}@ x); + float expintf(float x); + long double expintl(long double x); // \ref{sf.cmath.hermite}, Hermite polynomials - @\placeholder{floating-point-type}@ hermite(unsigned n, @\placeholder{floating-point-type}@ x); - float hermitef(unsigned n, float x); - long double hermitel(unsigned n, long double x); + @\placeholdernc{floating-point-type}@ hermite(unsigned n, @\placeholdernc{floating-point-type}@ x); + float hermitef(unsigned n, float x); + long double hermitel(unsigned n, long double x); // \ref{sf.cmath.laguerre}, Laguerre polynomials - @\placeholder{floating-point-type}@ laguerre(unsigned n, @\placeholder{floating-point-type}@ x); - float laguerref(unsigned n, float x); - long double laguerrel(unsigned n, long double x); + @\placeholdernc{floating-point-type}@ laguerre(unsigned n, @\placeholdernc{floating-point-type}@ x); + float laguerref(unsigned n, float x); + long double laguerrel(unsigned n, long double x); // \ref{sf.cmath.legendre}, Legendre polynomials - @\placeholder{floating-point-type}@ legendre(unsigned l, @\placeholder{floating-point-type}@ x); - float legendref(unsigned l, float x); - long double legendrel(unsigned l, long double x); + @\placeholdernc{floating-point-type}@ legendre(unsigned l, @\placeholdernc{floating-point-type}@ x); + float legendref(unsigned l, float x); + long double legendrel(unsigned l, long double x); // \ref{sf.cmath.riemann.zeta}, Riemann zeta function - @\placeholder{floating-point-type}@ riemann_zeta(@\placeholder{floating-point-type}@ x); - float riemann_zetaf(float x); - long double riemann_zetal(long double x); + @\placeholdernc{floating-point-type}@ riemann_zeta(@\placeholdernc{floating-point-type}@ x); + float riemann_zetaf(float x); + long double riemann_zetal(long double x); // \ref{sf.cmath.sph.bessel}, spherical Bessel functions of the first kind - @\placeholder{floating-point-type}@ sph_bessel(unsigned n, @\placeholder{floating-point-type}@ x); - float sph_besself(unsigned n, float x); - long double sph_bessell(unsigned n, long double x); + @\placeholdernc{floating-point-type}@ sph_bessel(unsigned n, @\placeholdernc{floating-point-type}@ x); + float sph_besself(unsigned n, float x); + long double sph_bessell(unsigned n, long double x); // \ref{sf.cmath.sph.legendre}, spherical associated Legendre functions - @\placeholder{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ theta); - float sph_legendref(unsigned l, unsigned m, float theta); - long double sph_legendrel(unsigned l, unsigned m, long double theta); + @\placeholdernc{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholdernc{floating-point-type}@ theta); + float sph_legendref(unsigned l, unsigned m, float theta); + long double sph_legendrel(unsigned l, unsigned m, long double theta); // \ref{sf.cmath.sph.neumann}, spherical Neumann functions; // spherical Bessel functions of the second kind - @\placeholder{floating-point-type}@ sph_neumann(unsigned n, @\placeholder{floating-point-type}@ x); - float sph_neumannf(unsigned n, float x); - long double sph_neumannl(unsigned n, long double x); + @\placeholdernc{floating-point-type}@ sph_neumann(unsigned n, @\placeholdernc{floating-point-type}@ x); + float sph_neumannf(unsigned n, float x); + long double sph_neumannl(unsigned n, long double x); } \end{codeblock} @@ -9648,13 +10006,17 @@ \pnum \returns -\[ \mathsf{L}_n^m(x) = - (-1)^m \frac{\mathsf{d} ^ m}{\mathsf{d}x ^ m} \, \mathsf{L}_{n+m}(x) - \text{ ,\quad for $x \ge 0$,} \] -where +$\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}. +\begin{formula}{sf.cmath.assoc.laguerre} +\mathsf{L}_n^m(x) = + (-1)^m \frac{\mathsf{d} ^ m}{\mathsf{d}x ^ m} \, \mathsf{L}_{n+m}(x) + \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -9686,13 +10048,17 @@ \pnum \returns -\[ \mathsf{P}_\ell^m(x) = (1 - x^2) ^ {m/2} \: - \frac{\mathsf{d} ^ m}{\mathsf{d}x ^ m} \, \mathsf{P}_\ell(x) - \text{ ,\quad for $|x| \le 1$,} \] -where -$l$ is \tcode{l}, +$\mathsf{P}_\ell^m(x)$, +where $\mathsf{P}_\ell^m$ is given by \eqref{sf.cmath.assoc.legendre}, +$\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} +\mathsf{P}_\ell^m(x) = (1 - x^2) ^ {m/2} \: + \frac{\mathsf{d} ^ m}{\mathsf{d}x ^ m} \, \mathsf{P}_\ell(x) + \text{ ,\quad for $|x| \le 1$} +\end{formula} \pnum \remarks @@ -9723,11 +10089,14 @@ \pnum \returns -\[ \mathsf{B}(x, y) = \frac{\Gamma(x) \, \Gamma(y)}{\Gamma(x + y)} - \text{ ,\quad for $x > 0$,\, $y > 0$,} \] -where +$\mathsf{B}(x, y)$, +where $\mathsf{B}$ is given by \eqref{sf.cmath.beta}, $x$ is \tcode{x} and $y$ is \tcode{y}. +\begin{formula}{sf.cmath.beta} +\mathsf{B}(x, y) = \frac{\Gamma(x) \, \Gamma(y)}{\Gamma(x + y)} + \text{ ,\quad for $x > 0$,\, $y > 0$} +\end{formula} \end{itemdescr} \rSec3[sf.cmath.comp.ellint.1]{Complete elliptic integral of the first kind}% @@ -9752,9 +10121,12 @@ \pnum \returns -\[ \mathsf{K}(k) = \mathsf{F}(k, \pi / 2) \text{ ,\quad for $|k| \le 1$,} \] -where +$\mathsf{K}(k)$, +where $\mathsf{K}$ is given by \eqref{sf.cmath.comp.ellint.1} and $k$ is \tcode{k}. +\begin{formula}{sf.cmath.comp.ellint.1} +\mathsf{K}(k) = \mathsf{F}(k, \pi / 2) \text{ ,\quad for $|k| \le 1$} +\end{formula} \pnum See also \ref{sf.cmath.ellint.1}. @@ -9782,9 +10154,12 @@ \pnum \returns -\[ \mathsf{E}(k) = \mathsf{E}(k, \pi / 2) \text{ ,\quad for $|k| \le 1$,} \] -where +$\mathsf{E}(k)$, +where $\mathsf{E}$ is given by \eqref{sf.cmath.comp.ellint.2} and $k$ is \tcode{k}. +\begin{formula}{sf.cmath.comp.ellint.2} +\mathsf{E}(k) = \mathsf{E}(k, \pi / 2) \text{ ,\quad for $|k| \le 1$} +\end{formula} \pnum See also \ref{sf.cmath.ellint.2}. @@ -9812,10 +10187,13 @@ \pnum \returns -\[ \mathsf{\Pi}(\nu, k) = \mathsf{\Pi}(\nu, k, \pi / 2) \text{ ,\quad for $|k| \le 1$,} \] -where -$k$ is \tcode{k} and +$\mathsf{\Pi}(\nu, k)$, +where $\mathsf{\Pi}$ is given by \eqref{sf.cmath.comp.ellint.3}, +$k$ is \tcode{k}, and $\nu$ is \tcode{nu}. +\begin{formula}{sf.cmath.comp.ellint.3} +\mathsf{\Pi}(\nu, k) = \mathsf{\Pi}(\nu, k, \pi / 2) \text{ ,\quad for $|k| \le 1$} +\end{formula} \pnum See also \ref{sf.cmath.ellint.3}. @@ -9826,7 +10204,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); @@ -9843,13 +10221,16 @@ \pnum \returns -\[ \mathsf{I}_\nu(x) = +$\mathsf{I}_\nu(x)$, +where $\mathsf{I}_\nu$ is given by \eqref{sf.cmath.cyl.bessel.i}, +$\nu$ is \tcode{nu}, and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.cyl.bessel.i} +\mathsf{I}_\nu(x) = \mathrm{i}^{-\nu} \mathsf{J}_\nu(\mathrm{i}x) = \sum_{k=0}^\infty \frac{(x/2)^{\nu+2k}}{k! \: \Gamma(\nu+k+1)} - \text{ ,\quad for $x \ge 0$,} \] -where -$\nu$ is \tcode{nu} and -$x$ is \tcode{x}. + \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -9866,7 +10247,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); @@ -9884,12 +10265,15 @@ \pnum \returns -\[ \mathsf{J}_\nu(x) = - \sum_{k=0}^\infty \frac{(-1)^k (x/2)^{\nu+2k}}{k! \: \Gamma(\nu+k+1)} - \text{ ,\quad for $x \ge 0$,} \] -where -$\nu$ is \tcode{nu} and +$\mathsf{J}_\nu(x)$, +where $\mathsf{J}_\nu$ is given by \eqref{sf.cmath.cyl.bessel.j}, +$\nu$ is \tcode{nu}, and $x$ is \tcode{x}. +\begin{formula}{sf.cmath.cyl.bessel.j} +\mathsf{J}_\nu(x) = + \sum_{k=0}^\infty \frac{(-1)^k (x/2)^{\nu+2k}}{k! \: \Gamma(\nu+k+1)} + \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -9903,7 +10287,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); @@ -9921,7 +10305,11 @@ \pnum \returns -\[% +$\mathsf{K}_\nu(x)$, +where $\mathsf{K}_\nu$ is given by \eqref{sf.cmath.cyl.bessel.k}, +$\nu$ is \tcode{nu}, and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.cyl.bessel.k} \mathsf{K}_\nu(x) = (\pi/2)\mathrm{i}^{\nu+1} ( \mathsf{J}_\nu(\mathrm{i}x) + \mathrm{i} \mathsf{N}_\nu(\mathrm{i}x) @@ -9943,10 +10331,7 @@ & \mbox{for $x \ge 0$ and integral $\nu$} \end{array} \right. -\] -where -$\nu$ is \tcode{nu} and -$x$ is \tcode{x}. +\end{formula} \pnum \remarks @@ -9982,7 +10367,11 @@ \pnum \returns -\[% +$\mathsf{N}_\nu(x)$, +where $\mathsf{N}_\nu$ is given by \eqref{sf.cmath.cyl.neumann}, +$\nu$ is \tcode{nu}, and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.cyl.neumann} \mathsf{N}_\nu(x) = \left\{ \begin{array}{cl} @@ -9998,10 +10387,7 @@ & \mbox{for $x \ge 0$ and integral $\nu$} \end{array} \right. -\] -where -$\nu$ is \tcode{nu} and -$x$ is \tcode{x}. +\end{formula} \pnum \remarks @@ -10035,12 +10421,15 @@ \pnum \returns -\[ \mathsf{F}(k, \phi) = - \int_0^\phi \! \frac{\mathsf{d}\theta}{\sqrt{1 - k^2 \sin^2 \theta}} - \text{ ,\quad for $|k| \le 1$,} \] -where -$k$ is \tcode{k} and +$\mathsf{F}(k, \phi)$, +where $\mathsf{F}$ is given by \eqref{sf.cmath.ellint.1}, +$k$ is \tcode{k}, and $\phi$ is \tcode{phi}. +\begin{formula}{sf.cmath.ellint.1} +\mathsf{F}(k, \phi) = + \int_0^\phi \! \frac{\mathsf{d}\theta}{\sqrt{1 - k^2 \sin^2 \theta}} + \text{ ,\quad for $|k| \le 1$} +\end{formula} \end{itemdescr} \rSec3[sf.cmath.ellint.2]{Incomplete elliptic integral of the second kind}% @@ -10065,11 +10454,14 @@ \pnum \returns -\[ \mathsf{E}(k, \phi) = \int_0^\phi \! \sqrt{1 - k^2 \sin^2 \theta} \, \mathsf{d}\theta - \text{ ,\quad for $|k| \le 1$,} \] -where -$k$ is \tcode{k} and +$\mathsf{E}(k, \phi)$, +where $\mathsf{E}$ is given by \eqref{sf.cmath.ellint.2}, +$k$ is \tcode{k}, and $\phi$ is \tcode{phi}. +\begin{formula}{sf.cmath.ellint.2} +\mathsf{E}(k, \phi) = \int_0^\phi \! \sqrt{1 - k^2 \sin^2 \theta} \, \mathsf{d}\theta + \text{ ,\quad for $|k| \le 1$} +\end{formula} \end{itemdescr} \rSec3[sf.cmath.ellint.3]{Incomplete elliptic integral of the third kind}% @@ -10096,12 +10488,15 @@ \pnum \returns -\[ \mathsf{\Pi}(\nu, k, \phi) = \int_0^\phi \! - \frac{ \mathsf{d}\theta }{ (1 - \nu \, \sin^2 \theta) \sqrt{1 - k^2 \sin^2 \theta} } \text{ ,\quad for $|k| \le 1$,} \] -where +$\mathsf{\Pi}(\nu, k, \phi)$, +where $\mathsf{\Pi}$ is given by \eqref{sf.cmath.ellint.3}, $\nu$ is \tcode{nu}, $k$ is \tcode{k}, and $\phi$ is \tcode{phi}. +\begin{formula}{sf.cmath.ellint.3} +\mathsf{\Pi}(\nu, k, \phi) = \int_0^\phi \! + \frac{ \mathsf{d}\theta }{ (1 - \nu \, \sin^2 \theta) \sqrt{1 - k^2 \sin^2 \theta} } \text{ ,\quad for $|k| \le 1$} +\end{formula} \end{itemdescr} \rSec3[sf.cmath.expint]{Exponential integral}% @@ -10126,15 +10521,14 @@ \pnum \returns -\[% +$\mathsf{Ei}(x)$, +where $\mathsf{Ei}$ is given by \eqref{sf.cmath.expint} and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.expint} \mathsf{Ei}(x) = - \int_{-x}^\infty \frac{e^{-t}} {t } \, \mathsf{d}t -\; -\] -where -$x$ is \tcode{x}. - +\end{formula} \end{itemdescr} \rSec3[sf.cmath.hermite]{Hermite polynomials}% @@ -10158,15 +10552,15 @@ \pnum \returns -\[% +$\mathsf{H}_n(x)$, +where $\mathsf{H}_n$ is given by \eqref{sf.cmath.hermite}, +$n$ is \tcode{n}, and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.hermite} \mathsf{H}_n(x) = (-1)^n e^{x^2} \frac{ \mathsf{d} ^n} { \mathsf{d}x^n} \, e^{-x^2} -\; -\] -where -$n$ is \tcode{n} and -$x$ is \tcode{x}. +\end{formula} \pnum \remarks @@ -10196,12 +10590,15 @@ \pnum \returns -\[ \mathsf{L}_n(x) = - \frac{e^x}{n!} \frac{\mathsf{d}^n}{\mathsf{d}x^n} \, (x^n e^{-x}) - \text{ ,\quad for $x \ge 0$,} \] -where -$n$ is \tcode{n} and +$\mathsf{L}_n(x)$, +where $\mathsf{L}_n$ is given by \eqref{sf.cmath.laguerre}, +$n$ is \tcode{n}, and $x$ is \tcode{x}. +\begin{formula}{sf.cmath.laguerre} +\mathsf{L}_n(x) = + \frac{e^x}{n!} \frac{\mathsf{d}^n}{\mathsf{d}x^n} \, (x^n e^{-x}) + \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -10231,13 +10628,16 @@ \pnum \returns -\[ \mathsf{P}_\ell(x) = +$\mathsf{P}_\ell(x)$, +where $\mathsf{P}_\ell$ is given by \eqref{sf.cmath.legendre}, +$l$ is \tcode{l}, and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.legendre} +\mathsf{P}_\ell(x) = \frac{1}{2^\ell \, \ell!} \frac{\mathsf{d}^\ell}{\mathsf{d}x^\ell} \, (x^2 - 1) ^ \ell - \text{ ,\quad for $|x| \le 1$,} \] -where -$l$ is \tcode{l} and -$x$ is \tcode{x}. + \text{ ,\quad for $|x| \le 1$} +\end{formula} \pnum \remarks @@ -10267,7 +10667,10 @@ \pnum \returns -\[% +$\mathsf{\zeta}(x)$, +where $\mathsf{\zeta}$ is given by \eqref{sf.cmath.riemann.zeta} and +$x$ is \tcode{x}. +\begin{formula}{sf.cmath.riemann.zeta} \mathsf{\zeta}(x) = \left\{ \begin{array}{cl} @@ -10288,10 +10691,7 @@ & \mbox{for $x < 0$} \end{array} \right. -\; -\] -where -$x$ is \tcode{x}. +\end{formula} \end{itemdescr} \rSec3[sf.cmath.sph.bessel]{Spherical Bessel functions of the first kind}% @@ -10316,10 +10716,13 @@ \pnum \returns -\[ \mathsf{j}_n(x) = (\pi/2x)^{1\!/\!2} \mathsf{J}_{n + 1\!/\!2}(x) \text{ ,\quad for $x \ge 0$,} \] -where -$n$ is \tcode{n} and +$\mathsf{j}_n(x)$, +where $\mathsf{j}_n$ is given by \eqref{sf.cmath.sph.bessel}, +$n$ is \tcode{n}, and $x$ is \tcode{x}. +\begin{formula}{sf.cmath.sph.bessel} +\mathsf{j}_n(x) = (\pi/2x)^{1\!/\!2} \mathsf{J}_{n + 1\!/\!2}(x) \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -10353,17 +10756,17 @@ \pnum \returns -\[ \mathsf{Y}_\ell^m(\theta, 0) \] -where -\[ \mathsf{Y}_\ell^m(\theta, \phi) = - (-1)^m \left[\frac{(2 \ell + 1)}{4 \pi} \frac{(\ell - m)!}{(\ell + m)!}\right]^{1/2} - \mathsf{P}_\ell^m (\cos\theta) e^{i m \phi} - \text{ ,\quad for $|m| \le \ell$,} -\] -and +$\mathsf{Y}_\ell^m(\theta, 0)$, +where $\mathsf{Y}_\ell^m$ is given by \eqref{sf.cmath.sph.legendre}, $l$ is \tcode{l}, $m$ is \tcode{m}, and $\theta$ is \tcode{theta}. +\begin{formula}{sf.cmath.sph.legendre} +\mathsf{Y}_\ell^m(\theta, \phi) = + (-1)^m \left[\frac{(2 \ell + 1)}{4 \pi} \frac{(\ell - m)!}{(\ell + m)!}\right]^{1/2} + \mathsf{P}_\ell^m (\cos\theta) e^{i m \phi} + \text{ ,\quad for $|m| \le \ell$} +\end{formula} \pnum \remarks @@ -10398,11 +10801,14 @@ \pnum \returns -\[ \mathsf{n}_n(x) = (\pi/2x)^{1\!/\!2} \mathsf{N}_{n + 1\!/\!2}(x) - \text{ ,\quad for $x \ge 0$,} \] -where -$n$ is \tcode{n} and +$\mathsf{n}_n(x)$, +where $\mathsf{n}_n$ is given by \eqref{sf.cmath.sph.neumann}, +$n$ is \tcode{n}, and $x$ is \tcode{x}. +\begin{formula}{sf.cmath.sph.neumann} +\mathsf{n}_n(x) = (\pi/2x)^{1\!/\!2} \mathsf{N}_{n + 1\!/\!2}(x) + \text{ ,\quad for $x \ge 0$} +\end{formula} \pnum \remarks @@ -10423,19 +10829,19 @@ \indexheader{numbers}% \begin{codeblock} namespace std::numbers { - template constexpr T e_v = @\unspec@; - template constexpr T log2e_v = @\unspec@; - template constexpr T log10e_v = @\unspec@; - template constexpr T pi_v = @\unspec@; - template constexpr T inv_pi_v = @\unspec@; - template constexpr T inv_sqrtpi_v = @\unspec@; - template constexpr T ln2_v = @\unspec@; - template constexpr T ln10_v = @\unspec@; - template constexpr T sqrt2_v = @\unspec@; - template constexpr T sqrt3_v = @\unspec@; - template constexpr T inv_sqrt3_v = @\unspec@; - template constexpr T egamma_v = @\unspec@; - template constexpr T phi_v = @\unspec@; + template constexpr T @\libglobal{e_v}@ = @\unspec@; + template constexpr T @\libglobal{log2e_v}@ = @\unspec@; + template constexpr T @\libglobal{log10e_v}@ = @\unspec@; + template constexpr T @\libglobal{pi_v}@ = @\unspec@; + template constexpr T @\libglobal{inv_pi_v}@ = @\unspec@; + template constexpr T @\libglobal{inv_sqrtpi_v}@ = @\unspec@; + template constexpr T @\libglobal{ln2_v}@ = @\unspec@; + template constexpr T @\libglobal{ln10_v}@ = @\unspec@; + template constexpr T @\libglobal{sqrt2_v}@ = @\unspec@; + template constexpr T @\libglobal{sqrt3_v}@ = @\unspec@; + template constexpr T @\libglobal{inv_sqrt3_v}@ = @\unspec@; + template constexpr T @\libglobal{egamma_v}@ = @\unspec@; + template constexpr T @\libglobal{phi_v}@ = @\unspec@; template<@\libconcept{floating_point}@ T> constexpr T e_v = @\seebelow@; template<@\libconcept{floating_point}@ T> constexpr T log2e_v = @\seebelow@; @@ -10451,19 +10857,19 @@ template<@\libconcept{floating_point}@ T> constexpr T egamma_v = @\seebelow@; template<@\libconcept{floating_point}@ T> constexpr T phi_v = @\seebelow@; - inline constexpr double e = e_v; - inline constexpr double log2e = log2e_v; - inline constexpr double log10e = log10e_v; - inline constexpr double pi = pi_v; - inline constexpr double inv_pi = inv_pi_v; - inline constexpr double inv_sqrtpi = inv_sqrtpi_v; - inline constexpr double ln2 = ln2_v; - inline constexpr double ln10 = ln10_v; - inline constexpr double sqrt2 = sqrt2_v; - inline constexpr double sqrt3 = sqrt3_v; - inline constexpr double inv_sqrt3 = inv_sqrt3_v; - inline constexpr double egamma = egamma_v; - inline constexpr double phi = phi_v; + inline constexpr double @\libglobal{e}@ = e_v; + inline constexpr double @\libglobal{log2e}@ = log2e_v; + inline constexpr double @\libglobal{log10e}@ = log10e_v; + inline constexpr double @\libglobal{pi}@ = pi_v; + inline constexpr double @\libglobal{inv_pi}@ = inv_pi_v; + inline constexpr double @\libglobal{inv_sqrtpi}@ = inv_sqrtpi_v; + inline constexpr double @\libglobal{ln2}@ = ln2_v; + inline constexpr double @\libglobal{ln10}@ = ln10_v; + inline constexpr double @\libglobal{sqrt2}@ = sqrt2_v; + inline constexpr double @\libglobal{sqrt3}@ = sqrt3_v; + inline constexpr double @\libglobal{inv_sqrt3}@ = inv_sqrt3_v; + inline constexpr double @\libglobal{egamma}@ = egamma_v; + inline constexpr double @\libglobal{phi}@ = phi_v; } \end{codeblock} @@ -11359,7 +11765,7 @@ that is a multidimensional index in \tcode{x.extents()}, there exists a pack of integers \tcode{j} that is a multidimensional index in \tcode{y.extents()}, -such that \tcode{x[i....]} and \tcode{y[j...]} refer to the same element. +such that \tcode{x[i...]} and \tcode{y[j...]} refer to the same element. \begin{note} Aliasing is a special case of overlapping. If \tcode{x} and \tcode{y} do not overlap, @@ -11373,7 +11779,7 @@ \pnum Throughout \ref{linalg}, the following types are -\defnadjx{linear algebra}{value type}{linear algebra value types}: +\defnadjx{linear algebra}{value types}{value type}: \begin{itemize} \item the \tcode{value_type} type alias of @@ -11890,7 +12296,7 @@ if that expression is valid, with overload resolution performed in a context that includes the declaration \begin{codeblock} -template T abs(T) = delete; +template U abs(U) = delete; \end{codeblock} If the function selected by overload resolution does not return the absolute value of its input, @@ -11910,7 +12316,7 @@ the expression \tcode{conj(E)} is valid, with overload resolution performed in a context that includes the declaration \begin{codeblock} -template T conj(const T&) = delete; +template U conj(const U&) = delete; \end{codeblock} If the function selected by overload resolution does not return the complex conjugate of its input, @@ -11932,7 +12338,7 @@ the expression \tcode{real(E)} is valid, with overload resolution performed in a context that includes the declaration \begin{codeblock} -template T real(const T&) = delete; +template U real(const U&) = delete; \end{codeblock} If the function selected by overload resolution does not return the real part of its input, @@ -11954,7 +12360,7 @@ is valid, with overload resolution performed in a context that includes the declaration \begin{codeblock} -template T imag(const T&) = delete; +template U imag(const U&) = delete; \end{codeblock} If the function selected by overload resolution does not return the imaginary part of its input, @@ -12069,7 +12475,7 @@ bool @\exposid{compatible-static-extents}@(size_t r1, size_t r2) { // \expos return MDS1::static_extent(r1) == dynamic_extent || MDS2::static_extent(r2) == dynamic_extent || - MDS1::static_extent(r1) == MDS2::static_extent(r2)); + MDS1::static_extent(r1) == MDS2::static_extent(r2); } template<@\exposconcept{in-vector}@ In1, @\exposconcept{in-vector}@ In2, @\exposconcept{in-vector}@ Out> @@ -12146,7 +12552,7 @@ constexpr bool @\exposid{multipliable}@( // \expos const @\exposconcept{in-matrix}@ auto& in_mat1, const @\exposconcept{in-matrix}@ auto& in_mat2, const @\exposconcept{in-matrix}@ auto& out_mat) { return out_mat.extent(0) == in_mat1.extent(0) && out_mat.extent(1) == in_mat2.extent(1) && - in1_mat.extent(1) == in_mat2.extent(0); + in_mat1.extent(1) == in_mat2.extent(0); } \end{codeblock} @@ -12459,25 +12865,38 @@ \begin{itemdescr} \pnum Let \tcode{A} be +\begin{itemize} +\item \tcode{remove_cvref_t} -if \tcode{Accessor} is a specialization of \tcode{conjugated_accessor}, and -otherwise \tcode{conjugated_accessor}. +if \tcode{Accessor} is a specialization of \tcode{conjugated_accessor}; +\item +otherwise, +\tcode{Accessor} if \tcode{remove_cvref_t} is an arithmetic type; +\item +otherwise, +\tcode{conjugated_accessor} +if the expression \tcode{conj(E)} is valid for any subexpression \tcode{E} +whose type is \tcode{remove_cvref_t} +with overload resolution performed in a context that includes the declaration +\tcode{template U conj(const U\&) = delete;}; +\item +otherwise, +\tcode{Accessor}. +\end{itemize} \pnum \returns +Let \tcode{MD} be \tcode{mdspan}. \begin{itemize} \item -If \tcode{Accessor} is a specialization of \tcode{conjugated_accessor}, -\begin{codeblock} -mdspan(a.data_handle(), a.mapping(), - a.accessor().nested_accessor()) -\end{codeblock} +\tcode{MD(a.data_handle(), a.mapping(), a.accessor().nested_accessor())} +if \tcode{Accessor} is a\newline specialization of \tcode{conjugated_accessor}; \item otherwise, -\begin{codeblock} -mdspan(a.data_handle(), a.mapping(), - conjugated_accessor(a.accessor())) -\end{codeblock} +\tcode{a}, if \tcode{is_same_v} is \tcode{true}; +\item +otherwise, +\tcode{MD(a.data_handle(), a.mapping(), conjugated_accessor(a.accessor()))}. \end{itemize} \end{itemdescr} @@ -12717,6 +13136,14 @@ \item otherwise, \tcode{layout_left} if \tcode{Layout} is \tcode{layout_right}; \item +otherwise, \tcode{layout_right_padded} if \tcode{Layout} is\newline +\tcode{layout_left_padded} +for some \tcode{size_t} value \tcode{PaddingValue}; +\item +otherwise, \tcode{layout_left_padded} if \tcode{Layout} is\newline +\tcode{layout_right_padded} +for some \tcode{size_t} value \tcode{PaddingValue}; +\item otherwise, \tcode{layout_stride} if \tcode{Layout} is \tcode{layout_stride}; \item otherwise, @@ -12759,11 +13186,26 @@ a.accessor()) \end{codeblock} \item +otherwise, +\begin{codeblock} +R(a.data_handle(), ReturnMapping(@\exposid{transpose-extents}@(a.mapping().extents()), + a.mapping().stride(1)), a.accessor()) +\end{codeblock} +if \tcode{Layout} is \tcode{layout_left_padded} +for some \tcode{size_t} value \tcode{PaddingValue}; +\item +otherwise, +\begin{codeblock} +R(a.data_handle(), ReturnMapping(@\exposid{transpose-extents}@(a.mapping().extents()), + a.mapping().stride(0)), a.accessor()) +\end{codeblock} +if \tcode{Layout} is \tcode{layout_right_padded} +for some \tcode{size_t} value \tcode{PaddingValue}; +\item otherwise, if \tcode{Layout} is \tcode{layout_stride}, \begin{codeblock} R(a.data_handle(), ReturnMapping(@\exposid{transpose-extents}@(a.mapping().extents()), - array{a.mapping().stride(1), a.mapping().stride(0)}), - a.accessor()) + array{a.mapping().stride(1), a.mapping().stride(0)}), a.accessor()) \end{codeblock} \item otherwise, if \tcode{Layout} is a specialization of \tcode{layout_transpose}, @@ -12877,8 +13319,8 @@ \tcode{is_execution_policy::value} is \tcode{true}\iref{execpol.type}. \item -\tcode{Real} is any type such that \tcode{complex} is specified -\iref{complex.numbers.general}. +\tcode{Real} is any type such that \tcode{complex} is +specified\iref{complex.numbers.general}. \item \tcode{Triangle} is either \tcode{upper_triangle_t} or \tcode{lower_triangle_t}. \item @@ -13844,7 +14286,7 @@ \begin{itemdescr} \pnum -These functions performs an updating matrix-vector product. +These functions perform an updating matrix-vector product. \pnum \effects @@ -15685,3 +16127,3467 @@ A, t, d, B, divides{}); \end{codeblock} \end{itemdescr} + +\rSec1[simd]{Data-parallel types} + +\rSec2[simd.general]{General} + +\pnum +Subclause \ref{simd} defines data-parallel types and operations on these types. +\begin{note} +The intent is to support acceleration through data-parallel execution resources +where available, such as SIMD registers and instructions or execution units +driven by a common instruction decoder. +SIMD stands for ``Single Instruction Stream -- Multiple Data Stream''; +it is defined in Flynn 1966\supercite{flynn-taxonomy}. +\end{note} + +\pnum +The set of \defnadjx{vectorizable}{types}{type} comprises +\begin{itemize} + \item + all standard integer types, character types, and the types \tcode{float} and + \tcode{double}\iref{basic.fundamental}; + \item + \tcode{std::float16_t}, \tcode{std::float32_t}, and \tcode{std::float64_t} + if defined\iref{basic.extended.fp}; and + \item + \tcode{complex} where \tcode{T} is a vectorizable floating-point type. +\end{itemize} + +\pnum +The term \defnadj{data-parallel}{type} refers to all enabled specializations of +the \tcode{basic_simd} and \tcode{basic_simd_mask} class templates. +A \defnadj{data-parallel}{object} is an object of data-parallel type. + +\pnum +Each specialization of \tcode{basic_simd} or \tcode{basic_simd_mask} is either +enabled or disabled, as described in \ref{simd.overview} and +\ref{simd.mask.overview}. + +\pnum +A data-parallel type consists of one or more elements of an underlying +vectorizable type, called the \defnadj{element}{type}. +The number of elements is a constant for each data-parallel type and called the +\defn{width} of that type. +The elements in a data-parallel type are indexed from 0 to $\textrm{width} - 1$. + +\pnum +An \defnadj{element-wise}{operation} applies a specified operation to the +elements of one or more data-parallel objects. +Each such application is unsequenced with respect to the others. +A \defnadj{unary element-wise}{operation} is an element-wise operation that +applies a unary operation to each element of a data-parallel object. +A \defnadj{binary element-wise}{operation} is an element-wise operation that +applies a binary operation to corresponding elements of two data-parallel +objects. + +\pnum +Given a \tcode{basic_simd_mask} object \tcode{mask}, the +\defnadj{selected}{indices} signify the integers $i$ in the range +\range{0}{mask.size()} for which \tcode{mask[$i$]} is \tcode{true}. +Given a data-parallel object \tcode{data}, the \defnadj{selected}{elements} +signify the elements \tcode{data[$i$]} for all selected indices $i$. + +\pnum +The conversion from an arithmetic type \tcode{U} to a vectorizable type +\tcode{T} is \defn{value-preserving} if all possible values of \tcode{U} can be +represented with type \tcode{T}. + +\rSec2[simd.expos]{Exposition-only types, variables, and concepts} + +\begin{codeblock} +using @\exposidnc{simd-size-type} = \seebelownc@; // \expos +template using @\exposidnc{integer-from} = \seebelownc@; // \expos + +template + constexpr @\exposidnc{simd-size-type} \exposidnc{simd-size-v} = \seebelownc@; // \expos +template constexpr size_t @\exposidnc{mask-element-size} = \seebelownc@; // \expos + +template + concept @\defexposconceptnc{constexpr-wrapper-like}@ = // \expos + @\libconcept{convertible_to}@ && + @\libconcept{equality_comparable_with}@ && + bool_constant::value && + bool_constant(T()) == T::value>::value; + +template using @\exposidnc{deduced-simd-t} = \seebelownc@; // \expos + +template using @\exposidnc{make-compatible-simd-t} = \seebelownc@; // \expos + +template + concept @\defexposconceptnc{simd-type}@ = // \expos + @\libconcept{same_as}@> && + is_default_constructible_v; + +template + concept @\defexposconceptnc{simd-floating-point}@ = // \expos + @\exposconcept{simd-type}@ && @\libconcept{floating_point}@; + +template + using @\exposidnc{simd-complex-value-type}@ = typename V::value_type::value_type; // \expos + +template + concept @\defexposconceptnc{simd-complex}@ = // \expos + @\exposconcept{simd-type}@ && @\libconcept{same_as}@>>; + +template + concept @\defexposconceptnc{math-floating-point}@ = // \expos + (@\exposconceptnc{simd-floating-point}<\exposidnc{deduced-simd-t}@> || ...); + +template + requires @\exposconceptnc{math-floating-point}@ + using @\exposidnc{math-common-simd-t} = \seebelownc@; // \expos + +template + concept @\exposconceptnc{reduction-binary-operation} = \seebelownc@; // \expos + +// \ref{simd.expos.abi}, \tcode{simd} ABI tags +template using @\exposidnc{native-abi} = \seebelownc@; // \expos +template using @\exposidnc{deduce-abi-t} = \seebelownc@; // \expos + +// \ref{simd.flags}, Load and store flags +struct @\exposidnc{convert-flag}@; // \expos +struct @\exposidnc{aligned-flag}@; // \expos +template struct @\exposidnc{overaligned-flag}@; // \expos +\end{codeblock} + +\rSec3[simd.expos.defn]{Exposition-only helpers} + +\begin{itemdecl} +using @\exposid{simd-size-type}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\exposid{simd-size-type} is an alias for a signed integer type. +\end{itemdescr} + +\begin{itemdecl} +template using @\exposid{integer-from}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{\exposid{integer-from}} is an alias for a signed integer type +\tcode{T} such that \tcode{sizeof(T)} equals \tcode{Bytes}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr @\exposid{simd-size-type} \exposid{simd-size-v}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{\exposid{simd-size-v}} denotes the width of \tcode{basic_simd} if the specialization \tcode{basic_simd} is enabled, or \tcode{0} +otherwise. +\end{itemdescr} + +\begin{itemdecl} +template constexpr size_t @\exposid{mask-element-size}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{\exposid{mask-element-size}>} has the value +\tcode{Bytes}. +\end{itemdescr} + +\begin{itemdecl} +template using @\exposid{deduced-simd-t}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{x} denote an lvalue of type \tcode{const T}. + +\pnum +\tcode{\exposid{deduced-simd-t}} is an alias for +\begin{itemize} + \item + \tcode{decltype(x + x)}, if the type of \tcode{x + x} is an enabled + specialization of \tcode{basic_simd}; otherwise + \item + \tcode{void}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template using @\exposid{make-compatible-simd-t}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{x} denote an lvalue of type \tcode{const T}. +\pnum +\tcode{\exposid{make-compatible-simd-t}} is an alias for +\begin{itemize} + \item + \tcode{\exposid{deduced-simd-t}}, if that type is not \tcode{void}, + otherwise + \item + \tcode{simd}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + requires @\exposconcept{math-floating-point}@ + using @\exposid{math-common-simd-t}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{T0} denote \tcode{Ts...[0]}. +Let \tcode{T1} denote \tcode{Ts...[1]}. +Let \tcode{TRest} denote a pack such that \tcode{T0, T1, TRest...} is equivalent +to \tcode{Ts...}. + +\pnum +Let \tcode{\exposid{math-common-simd-t}} be an alias for +\begin{itemize} + \item + \tcode{\exposid{deduced-simd-t}}, if \tcode{sizeof...(Ts)} equals $1$; + otherwise + \item + \tcode{common_type_t<\exposid{deduced-simd-t}, + \exposid{deduced-simd-t}>}, if \tcode{sizeof...(Ts)} equals $2$ and + \tcode{\exposconcept{math-floating-point} \&\& + \exposconcept{math-floating-point}} is \tcode{true}; otherwise + \item + \tcode{common_type_t<\exposid{deduced-simd-t}, T1>}, if + \tcode{sizeof...(Ts)} equals $2$ and + \tcode{\exposconceptx{math-floating-\brk{}point}{math-floating-point}<\brk{}T0>} + is \tcode{true}; otherwise + \item + \tcode{common_type_t>}, if + \tcode{sizeof...(Ts)} equals $2$; otherwise + \item + \tcode{common_type_t<\exposid{math-common-simd-t}, TRest...>}, if + \tcode{\exposid{math-common-simd-t}} is valid and denotes a type; + otherwise + \item + \tcode{common_type_t<\exposid{math-common-simd-t}, T0, T1>}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + concept @\defexposconcept{reduction-binary-operation}@ = + requires (const BinaryOperation binary_op, const simd v) { + { binary_op(v, v) } -> @\libconcept{same_as}@>; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Types \tcode{BinaryOperation} and \tcode{T} model +\tcode{\exposconcept{reduction-binary-operation}} only if: +\begin{itemize} +\item \tcode{BinaryOperation} is a binary element-wise operation and the +operation is commutative. + +\item An object of type \tcode{BinaryOperation} can be invoked with two +arguments of type \tcode{basic_simd}, with unspecified ABI tag +\tcode{Abi}, returning a \tcode{basic_simd}. +\end{itemize} +\end{itemdescr} + +\rSec3[simd.expos.abi]{\tcode{simd} ABI tags} + +\begin{itemdecl} +template using @\exposid{native-abi}@ = @\seebelow@; +template using @\exposid{deduce-abi-t}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +An \defn{ABI tag} is a type that indicates a choice of size and binary +representation for objects of data-parallel type. +\begin{note} +The intent is for the size and binary representation to depend on the target +architecture and compiler flags. +The ABI tag, together with a given element type, implies the width. +\end{note} + +\pnum +\begin{note} +The ABI tag is orthogonal to selecting the machine instruction set. +The selected machine instruction set limits the usable ABI tag types, though +(see \ref{simd.overview}). +The ABI tags enable users to safely pass objects of data-parallel type between +translation unit boundaries (e.g., function calls or I/O). +\end{note} + +\pnum +An implementation defines ABI tag types as necessary for the following aliases. + +\pnum +\tcode{\exposid{deduce-abi-t}} is defined if +\begin{itemize} +\item \tcode{T} is a vectorizable type, +\item \tcode{N} is greater than zero, and +\item \tcode{N} is not larger than an implementation-defined maximum. +\end{itemize} +The \impldef{maximum width for \tcode{simd} and \tcode{simd_mask}} maximum for +\tcode{N} is not smaller than 64 and can differ depending on \tcode{T}. + +\pnum +Where present, \tcode{\exposid{deduce-abi-t}} names an ABI tag type such +that +\begin{itemize} + \item + \tcode{\exposid{simd-size-v}>} equals + \tcode{N}, \item \tcode{basic_simd>} is + enabled\iref{simd.overview}, and + \item + \tcode{basic_simd_mask, N>>} is enabled. +\end{itemize} + +\pnum +\tcode{\exposid{native-abi}} is an \impldef{default ABI tag for +\tcode{basic_simd} and \tcode{basic_simd_mask}} alias for an ABI tag. +\tcode{basic_simd>} is an enabled specialization. +\begin{note} +The intent is to use the ABI tag producing the most efficient data-parallel +execution for the element type \tcode{T} on the currently targeted system. +For target architectures with ISA extensions, compiler flags can change the type +of the \tcode{\exposid{native-abi}} alias. +\end{note} +\begin{example} +Consider a target architecture supporting the ABI tags \tcode{__simd128} and +\tcode{__simd256}, where hardware support for \tcode{__simd256} exists only for +floating-point types. +The implementation therefore defines \tcode{\exposid{native-abi}} as an alias +for +\begin{itemize} +\item \tcode{__simd256} if \tcode{T} is a floating-point type, and +\item \tcode{__simd128} otherwise. +\end{itemize} +\end{example} +\end{itemdescr} + +\rSec2[simd.syn]{Header \tcode{} synopsis} +\indexheader{simd}% +\begin{codeblock} +namespace std::datapar { + // \ref{simd.traits}, \tcode{simd} type traits + template struct alignment; + template + constexpr size_t alignment_v = alignment::value; + + template struct rebind { using type = @\seebelow@; }; + template using rebind_t = typename rebind::type; + template<@\exposid{simd-size-type}@ N, class V> struct resize { using type = @\seebelow@; }; + template<@\exposid{simd-size-type}@ N, class V> using resize_t = typename resize::type; + + // \ref{simd.flags}, Load and store flags + template struct flags; + inline constexpr flags<> flag_default{}; + inline constexpr flags<@\exposid{convert-flag}@> flag_convert{}; + inline constexpr flags<@\exposid{aligned-flag}@> flag_aligned{}; + template requires (has_single_bit(N)) + constexpr flags<@\exposid{overaligned-flag}@> flag_overaligned{}; + + // \ref{simd.class}, Class template \tcode{basic_simd} + template> class basic_simd; + template>> + using simd = basic_simd>; + + // \ref{simd.mask.class}, Class template \tcode{basic_simd_mask} + template>> class basic_simd_mask; + template>> + using simd_mask = basic_simd_mask>; + + // \ref{simd.loadstore}, \tcode{basic_simd} load and store functions + template + requires ranges::@\libconcept{sized_range}@ + constexpr V unchecked_load(R&& r, flags f = {}); + template + requires ranges::@\libconcept{sized_range}@ + constexpr V unchecked_load(R&& r, const typename V::mask_type& k, + flags f = {}); + template + constexpr V unchecked_load(I first, iter_difference_t n, + flags f = {}); + template + constexpr V unchecked_load(I first, iter_difference_t n, + const typename V::mask_type& k, flags f = {}); + template S, class... Flags> + constexpr V unchecked_load(I first, S last, flags f = {}); + template S, class... Flags> + constexpr V unchecked_load(I first, S last, const typename V::mask_type& k, + flags f = {}); + + template + requires ranges::@\libconcept{sized_range}@ + constexpr V partial_load(R&& r, flags f = {}); + template + requires ranges::@\libconcept{sized_range}@ + constexpr V partial_load(R&& r, const typename V::mask_type& k, + flags f = {}); + template + constexpr V partial_load(I first, iter_difference_t n, flags f = {}); + template + constexpr V partial_load(I first, iter_difference_t n, + const typename V::mask_type& k, flags f = {}); + template S, class... Flags> + constexpr V partial_load(I first, S last, flags f = {}); + template S, class... Flags> + constexpr V partial_load(I first, S last, const typename V::mask_type& k, + flags f = {}); + + template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void unchecked_store(const basic_simd& v, R&& r, + flags f = {}); + template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void unchecked_store(const basic_simd& v, R&& r, + const typename basic_simd::mask_type& mask, flags f = {}); + template + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, + iter_difference_t n, flags f = {}); + template + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, + iter_difference_t n, const typename basic_simd::mask_type& mask, + flags f = {}); + template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, S last, + flags f = {}); + template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, S last, + const typename basic_simd::mask_type& mask, flags f = {}); + + template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void partial_store(const basic_simd& v, R&& r, + flags f = {}); + template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void partial_store(const basic_simd& v, R&& r, + const typename basic_simd::mask_type& mask, flags f = {}); + template + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store( + const basic_simd& v, I first, iter_difference_t n, flags f = {}); + template + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store( + const basic_simd& v, I first, iter_difference_t n, + const typename basic_simd::mask_type& mask, flags f = {}); + template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, S last, + flags f = {}); + template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, S last, + const typename basic_simd::mask_type& mask, flags f = {}); + + // \ref{simd.creation}, \tcode{basic_simd} and \tcode{basic_simd_mask} creation + template + constexpr auto chunk(const basic_simd& x) noexcept; + template + constexpr auto chunk(const basic_simd_mask<@\exposid{mask-element-size}@, Abi>& x) noexcept; + + template + constexpr auto chunk(const basic_simd& x) noexcept; + template + constexpr auto chunk(const basic_simd_mask& x) noexcept; + + template + constexpr basic_simd::size() + ...)>> + cat(const basic_simd&...) noexcept; + template + constexpr basic_simd_mask, + (basic_simd_mask::size() + ...)>> + cat(const basic_simd_mask&...) noexcept; + + // \ref{simd.mask.reductions}, \tcode{basic_simd_mask} reductions + template + constexpr bool all_of(const basic_simd_mask&) noexcept; + template + constexpr bool any_of(const basic_simd_mask&) noexcept; + template + constexpr bool none_of(const basic_simd_mask&) noexcept; + template + constexpr @\exposid{simd-size-type}@ reduce_count(const basic_simd_mask&) noexcept; + template + constexpr @\exposid{simd-size-type}@ reduce_min_index(const basic_simd_mask&); + template + constexpr @\exposid{simd-size-type}@ reduce_max_index(const basic_simd_mask&); + + constexpr bool all_of(@\libconcept{same_as}@ auto) noexcept; + constexpr bool any_of(@\libconcept{same_as}@ auto) noexcept; + constexpr bool none_of(@\libconcept{same_as}@ auto) noexcept; + constexpr @\exposid{simd-size-type}@ reduce_count(@\libconcept{same_as}@ auto) noexcept; + constexpr @\exposid{simd-size-type}@ reduce_min_index(@\libconcept{same_as}@ auto); + constexpr @\exposid{simd-size-type}@ reduce_max_index(@\libconcept{same_as}@ auto); + + // \ref{simd.reductions}, \tcode{basic_simd} reductions + template> + constexpr T reduce(const basic_simd&, BinaryOperation = {}); + template> + constexpr T reduce( + const basic_simd& x, const typename basic_simd::mask_type& mask, + BinaryOperation binary_op = {}, type_identity_t identity_element = @\seebelow@); + + template + constexpr T reduce_min(const basic_simd&) noexcept; + template + constexpr T reduce_min(const basic_simd&, + const typename basic_simd::mask_type&) noexcept; + template + constexpr T reduce_max(const basic_simd&) noexcept; + template + constexpr T reduce_max(const basic_simd&, + const typename basic_simd::mask_type&) noexcept; + + // \ref{simd.alg}, Algorithms + template + constexpr basic_simd + min(const basic_simd& a, const basic_simd& b) noexcept; + template + constexpr basic_simd + max(const basic_simd& a, const basic_simd& b) noexcept; + template + constexpr pair, basic_simd> + minmax(const basic_simd& a, const basic_simd& b) noexcept; + template + constexpr basic_simd + clamp(const basic_simd& v, const basic_simd& lo, + const basic_simd& hi); + + template + constexpr auto select(bool c, const T& a, const U& b) + -> remove_cvref_t; + template + constexpr auto select(const basic_simd_mask& c, const T& a, const U& b) + noexcept -> decltype(@\exposid{simd-select-impl}@(c, a, b)); + + // \ref{simd.math}, Mathematical functions + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ acos(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ asin(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ atan(const V& x); + template + constexpr @\exposid{math-common-simd-t}@ atan2(const V0& y, const V1& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cos(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sin(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tan(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ acosh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ asinh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ atanh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cosh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sinh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tanh(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ exp(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ exp2(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ expm1(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ + frexp(const V& value, rebind_t>* exp); + template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> ilogb(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ ldexp(const V& x, const + rebind_t>& exp); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log10(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log1p(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log2(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ logb(const V& x); + template + constexpr basic_simd modf(const type_identity_t>& value, + basic_simd* iptr); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ scalbn(const V& x, const + rebind_t>& n); + template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ scalbln( + const V& x, const rebind_t>& n); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cbrt(const V& x); + template<@\libconcept{signed_integral}@ T, class Abi> + constexpr basic_simd abs(const basic_simd& j); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ abs(const V& j); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ fabs(const V& x); + template + constexpr @\exposid{math-common-simd-t}@ hypot(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ hypot(const V0& x, const V1& y, const V2& z); + template + constexpr @\exposid{math-common-simd-t}@ pow(const V0& x, const V1& y); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sqrt(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ erf(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ erfc(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ lgamma(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tgamma(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ ceil(const V& x); + template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ floor(const V& x); + template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ nearbyint(const V& x); + template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ rint(const V& x); + template<@\exposconcept{math-floating-point}@ V> + rebind_t> lrint(const V& x); + template<@\exposconcept{math-floating-point}@ V> + rebind_t llrint(const @\exposid{deduced-simd-t}@& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ round(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> lround(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> llround(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ trunc(const V& x); + template + constexpr @\exposid{math-common-simd-t}@ fmod(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ remainder(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ + remquo(const V0& x, const V1& y, rebind_t>* quo); + template + constexpr @\exposid{math-common-simd-t}@ copysign(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ nextafter(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ fdim(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ fmax(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ fmin(const V0& x, const V1& y); + template + constexpr @\exposid{math-common-simd-t}@ fma(const V0& x, const V1& y, const V2& z); + template + constexpr @\exposid{math-common-simd-t}@ + lerp(const V0& a, const V1& b, const V2& t) noexcept; + template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> fpclassify(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isfinite(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isinf(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isnan(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isnormal(const V& x); + template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type signbit(const V& x); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + isgreater(const V0& x, const V1& y); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + isgreaterequal(const V0& x, const V1& y); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + isless(const V0& x, const V1& y); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + islessequal(const V0& x, const V1& y); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + islessgreater(const V0& x, const V1& y); + template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + isunordered(const V0& x, const V1& y); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ assoc_laguerre(const rebind_t>& n, const + rebind_t>& m, + const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ assoc_legendre(const rebind_t>& l, const + rebind_t>& m, + const V& x); + template + @\exposid{math-common-simd-t}@ beta(const V0& x, const V1& y); + template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ comp_ellint_1(const V& k); + template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ comp_ellint_2(const V& k); + template + @\exposid{math-common-simd-t}@ comp_ellint_3(const V0& k, const V1& nu); + template + @\exposid{math-common-simd-t}@ cyl_bessel_i(const V0& nu, const V1& x); + template + @\exposid{math-common-simd-t}@ cyl_bessel_j(const V0& nu, const V1& x); + template + @\exposid{math-common-simd-t}@ cyl_bessel_k(const V0& nu, const V1& x); + template + @\exposid{math-common-simd-t}@ cyl_neumann(const V0& nu, const V1& x); + template + @\exposid{math-common-simd-t}@ ellint_1(const V0& k, const V1& phi); + template + @\exposid{math-common-simd-t}@ ellint_2(const V0& k, const V1& phi); + template + @\exposid{math-common-simd-t}@ ellint_3(const V0& k, const V1& nu, const V2& phi); + template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ expint(const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ hermite(const rebind_t>& n, const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ laguerre(const rebind_t>& n, const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ legendre(const rebind_t>& l, const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ riemann_zeta(const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ sph_bessel( + const rebind_t>& n, const V& x); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ sph_legendre(const rebind_t>& l, + const rebind_t>& m, const V& theta); + template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ + sph_neumann(const rebind_t>& n, const V& x); + + // \ref{simd.bit}, Bit manipulation + template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept; + + template<@\exposconcept{simd-type}@ V> + constexpr typename V::mask_type has_single_bit(const V& v) noexcept; + + template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotl(const V0& v, const V1& s) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr V rotl(const V& v, int s) noexcept; + + template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotr(const V0& v, const V1& s) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr V rotr(const V& v, int s) noexcept; + + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> bit_width(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> + countl_zero(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countl_one(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> + countr_zero(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countr_one(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> popcount(const V& v) noexcept; + + // \ref{simd.complex.math}, simd complex math + template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> real(const V&) noexcept; + + template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> imag(const V&) noexcept; + + template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> abs(const V&); + + template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> arg(const V&); + + template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> norm(const V&); + + template<@\exposconcept{simd-complex}@ V> constexpr V conj(const V&); + template<@\exposconcept{simd-complex}@ V> constexpr V proj(const V&); + template<@\exposconcept{simd-complex}@ V> constexpr V exp(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V log(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V log10(const V& v); + + template<@\exposconcept{simd-complex}@ V> constexpr V sqrt(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V sin(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V asin(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V cos(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V acos(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V tan(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V atan(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V sinh(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V asinh(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V cosh(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V acosh(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V tanh(const V& v); + template<@\exposconcept{simd-complex}@ V> constexpr V atanh(const V& v); + + template<@\exposconcept{simd-floating-point}@ V> + rebind_t, V> polar(const V& x, const V& y = {}); + + template<@\exposconcept{simd-complex}@ V> constexpr V pow(const V& x, const V& y); +} + +namespace std { + // See \ref{simd.alg}, Algorithms + using datapar::min; + using datapar::max; + using datapar::minmax; + using datapar::clamp; + + // See \ref{simd.math}, Mathematical functions + using datapar::acos; + using datapar::asin; + using datapar::atan; + using datapar::atan2; + using datapar::cos; + using datapar::sin; + using datapar::tan; + using datapar::acosh; + using datapar::asinh; + using datapar::atanh; + using datapar::cosh; + using datapar::sinh; + using datapar::tanh; + using datapar::exp; + using datapar::exp2; + using datapar::expm1; + using datapar::frexp; + using datapar::ilogb; + using datapar::ldexp; + using datapar::log; + using datapar::log10; + using datapar::log1p; + using datapar::log2; + using datapar::logb; + using datapar::modf; + using datapar::scalbn; + using datapar::scalbln; + using datapar::cbrt; + using datapar::abs; + using datapar::abs; + using datapar::fabs; + using datapar::hypot; + using datapar::pow; + using datapar::sqrt; + using datapar::erf; + using datapar::erfc; + using datapar::lgamma; + using datapar::tgamma; + using datapar::ceil; + using datapar::floor; + using datapar::nearbyint; + using datapar::rint; + using datapar::lrint; + using datapar::llrint; + using datapar::round; + using datapar::lround; + using datapar::llround; + using datapar::trunc; + using datapar::fmod; + using datapar::remainder; + using datapar::remquo; + using datapar::copysign; + using datapar::nextafter; + using datapar::fdim; + using datapar::fmax; + using datapar::fmin; + using datapar::fma; + using datapar::lerp; + using datapar::fpclassify; + using datapar::isfinite; + using datapar::isinf; + using datapar::isnan; + using datapar::isnormal; + using datapar::signbit; + using datapar::isgreater; + using datapar::isgreaterequal; + using datapar::isless; + using datapar::islessequal; + using datapar::islessgreater; + using datapar::isunordered; + using datapar::assoc_laguerre; + using datapar::assoc_legendre; + using datapar::beta; + using datapar::comp_ellint_1; + using datapar::comp_ellint_2; + using datapar::comp_ellint_3; + using datapar::cyl_bessel_i; + using datapar::cyl_bessel_j; + using datapar::cyl_bessel_k; + using datapar::cyl_neumann; + using datapar::ellint_1; + using datapar::ellint_2; + using datapar::ellint_3; + using datapar::expint; + using datapar::hermite; + using datapar::laguerre; + using datapar::legendre; + using datapar::riemann_zeta; + using datapar::sph_bessel; + using datapar::sph_legendre; + using datapar::sph_neumann; + + // See \ref{simd.bit}, Bit manipulation + using datapar::byteswap; + using datapar::bit_ceil; + using datapar::bit_floor; + using datapar::has_single_bit; + using datapar::rotl; + using datapar::rotr; + using datapar::bit_width; + using datapar::countl_zero; + using datapar::countl_one; + using datapar::countr_zero; + using datapar::countr_one; + using datapar::popcount; + + // See \ref{simd.complex.math}, simd complex math + using datapar::real; + using datapar::imag; + using datapar::arg; + using datapar::norm; + using datapar::conj; + using datapar::proj; + using datapar::polar; +} +\end{codeblock} + +\rSec2[simd.traits]{\tcode{simd} type traits} + +\begin{itemdecl} +template struct alignment { @\seebelow@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{alignment} has a member \tcode{value} if and only if +\begin{itemize} + \item + \tcode{T} is a specialization of \tcode{basic_simd_mask} and \tcode{U} is + \tcode{bool}, or + \item + \tcode{T} is a specialization of \tcode{basic_simd} and \tcode{U} is a + vectorizable type. +\end{itemize} + +\pnum +If \tcode{value} is present, the type \tcode{alignment} is a +\tcode{BinaryTypeTrait} with a base characteristic of +\tcode{integral_constant} for some unspecified +\tcode{N}\iref{simd.ctor,simd.loadstore}. +\begin{note} +\tcode{value} identifies the alignment restrictions on pointers used for +(converting) loads and stores for the given type \tcode{T} on arrays of type +\tcode{U}. +\end{note} + +\pnum +The behavior of a program that adds specializations for \tcode{alignment} +is undefined. +\end{itemdescr} + +\begin{itemdecl} +template struct rebind { using type = @\seebelow@; }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The member \tcode{type} is present if and only if +\begin{itemize} +\item \tcode{V} is a data-parallel type, +\item \tcode{T} is a vectorizable type, and +\item \tcode{\exposid{deduce-abi-t}} has a member type + \tcode{type}. +\end{itemize} + +\pnum +If \tcode V is a specialization of \tcode{basic_simd}, let \tcode{Abi1} denote +an ABI tag such that \tcode{basic_simd::\brk{}size()} equals +\tcode{V::size()}. +If \tcode V is a specialization of \tcode{basic_simd_mask}, let \tcode{Abi1} +denote an ABI tag such that \tcode{basic_simd_mask::\brk{}size()} equals \tcode{V::size()}. + +\pnum +Where present, the member typedef \tcode{type} names \tcode{basic_simd} +if \tcode V is a specialization of \tcode{basic_simd} or +\tcode{basic_simd_mask} if \tcode V is a specialization of +\tcode{basic_simd_mask}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposid{simd-size-type}@ N, class V> struct resize { using type = @\seebelow@; }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{T} denote +\begin{itemize} + \item + \tcode{typename V::value_type} if \tcode{V} is a specialization of + \tcode{basic_simd}, + \item + otherwise \tcode{\exposid{integer-from}<\exposid{mask-element-size}>} if + \tcode{V} is a specialization of \tcode{basic_simd_mask}. +\end{itemize} + +\pnum +The member \tcode{type} is present if and only if +\begin{itemize} +\item \tcode{V} is a data-parallel type, and +\item \tcode{\exposid{deduce-abi-t}} has a member type \tcode{type}. +\end{itemize} + +\pnum +If \tcode V is a specialization of \tcode{basic_simd}, let \tcode{Abi1} denote an +ABI tag such that \tcode{basic_simd::\brk{}size()} equals +\tcode{V::size()}. +If \tcode V is a specialization of \tcode{basic_simd_mask}, let \tcode{Abi1} +denote an ABI tag such that \tcode{basic_simd_mask::\brk{}size()} equals \tcode{V::size()}. + +\pnum +Where present, the member typedef \tcode{type} names \tcode{basic_simd} +if \tcode V is a specialization of \tcode{basic_simd} or +\tcode{basic_simd_mask} if \tcode V is a specialization of +\tcode{basic_simd_mask}. +\end{itemdescr} + +\rSec2[simd.flags]{Load and store flags} + +\rSec3[simd.flags.overview]{Class template \tcode{flags} overview} + +\begin{codeblock} +namespace std::datapar { + template struct flags { + // \ref{simd.flags.oper}, \tcode{flags} operators + template + friend consteval auto operator|(flags, flags); + }; +} +\end{codeblock} + +\pnum +\begin{note} +The class template \tcode{flags} acts like an integer bit-flag for types. +\end{note} + +\pnum +\constraints +Every type in the parameter pack \tcode{Flags} is one of \tcode{\exposid{convert-flag}}, +\tcode{\exposid{aligned-flag}}, or \tcode{\exposid{over\-aligned-\brk{}flag}}. + +\rSec3[simd.flags.oper]{\tcode{flags} operators} + +\begin{itemdecl} +template + friend consteval auto operator|(flags a, flags b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns + A default-initialized object of type \tcode{flags} for some + \tcode{Flags2} where every type in \tcode{Flags2} is present either in template parameter pack + \tcode{Flags} or in template parameter pack \tcode{Other}, and every type in template parameter + packs \tcode{Flags} and \tcode{Other} is present in \tcode{Flags2}. + If the packs \tcode{Flags} and \tcode{Other} contain two + different specializations \tcode{\exposid{overaligned-flag}} and + \tcode{\exposid{overaligned-flag}}, \tcode{Flags2} is not required to contain the + specialization \tcode{\exposid{overaligned-flag}}. +\end{itemdescr} + +\rSec2[simd.class]{Class template \tcode{basic_simd}} + +\rSec3[simd.overview]{Class template \tcode{basic_simd} overview} + +\begin{codeblock} +namespace std::datapar { + template class basic_simd { + public: + using value_type = T; + using mask_type = basic_simd_mask; + using abi_type = Abi; + + static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@> size {}; + + constexpr basic_simd() noexcept = default; + + // \ref{simd.ctor}, \tcode{basic_simd} constructors + template constexpr explicit(@\seebelow@) basic_simd(U&& value) noexcept; + template + constexpr explicit(@\seebelow@) basic_simd(const basic_simd&) noexcept; + template constexpr explicit basic_simd(G&& gen) noexcept; + template + constexpr basic_simd(R&& range, flags = {}); + template + constexpr basic_simd(R&& range, const mask_type& mask, flags = {}); + template<@\exposconcept{simd-floating-point}@ V> + constexpr explicit(@\seebelow@) basic_simd(const V& reals, const V& imags = {}) noexcept; + + // \ref{simd.subscr}, \tcode{basic_simd} subscript operators + constexpr value_type operator[](@\exposid{simd-size-type}@) const; + + // \ref{simd.unary}, \tcode{basic_simd} unary operators + constexpr basic_simd& operator++() noexcept; + constexpr basic_simd operator++(int) noexcept; + constexpr basic_simd& operator--() noexcept; + constexpr basic_simd operator--(int) noexcept; + constexpr mask_type operator!() const noexcept; + constexpr basic_simd operator~() const noexcept; + constexpr basic_simd operator+() const noexcept; + constexpr basic_simd operator-() const noexcept; + + // \ref{simd.binary}, \tcode{basic_simd} binary operators + friend constexpr basic_simd operator+(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator-(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator*(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator/(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator%(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator&(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator|(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator^(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator<<(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator>>(const basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd operator<<(const basic_simd&, @\exposid{simd-size-type}@) noexcept; + friend constexpr basic_simd operator>>(const basic_simd&, @\exposid{simd-size-type}@) noexcept; + + // \ref{simd.cassign}, \tcode{basic_simd} compound assignment + friend constexpr basic_simd& operator+=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator-=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator*=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator/=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator%=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator&=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator|=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator^=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator<<=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator>>=(basic_simd&, const basic_simd&) noexcept; + friend constexpr basic_simd& operator<<=(basic_simd&, @\exposid{simd-size-type}@) noexcept; + friend constexpr basic_simd& operator>>=(basic_simd&, @\exposid{simd-size-type}@) noexcept; + + // \ref{simd.comparison}, \tcode{basic_simd} compare operators + friend constexpr mask_type operator==(const basic_simd&, const basic_simd&) noexcept; + friend constexpr mask_type operator!=(const basic_simd&, const basic_simd&) noexcept; + friend constexpr mask_type operator>=(const basic_simd&, const basic_simd&) noexcept; + friend constexpr mask_type operator<=(const basic_simd&, const basic_simd&) noexcept; + friend constexpr mask_type operator>(const basic_simd&, const basic_simd&) noexcept; + friend constexpr mask_type operator<(const basic_simd&, const basic_simd&) noexcept; + + // \ref{simd.complex.access}, \tcode{basic_simd} complex-value accessors + constexpr auto real() const noexcept; + constexpr auto imag() const noexcept; + template<@\exposconcept{simd-floating-point}@ V> + constexpr void real(const V& v) noexcept; + template<@\exposconcept{simd-floating-point}@ V> + constexpr void imag(const V& v) noexcept; + + // \ref{simd.cond}, \tcode{basic_simd} exposition only conditional operators + friend constexpr basic_simd @\exposid{simd-select-impl}@( // \expos + const mask_type&, const basic_simd&, const basic_simd&) noexcept; + }; + + template + basic_simd(R&& r, Ts...) -> @\seebelow@; +} +\end{codeblock} + +\pnum +Every specialization of \tcode{basic_simd} is a complete type. +The specialization of \tcode{basic_simd} is +\begin{itemize} + \item + enabled, if \tcode{T} is a vectorizable type, and there exists value + \tcode{N} in the range \crange{1}{64}, such that \tcode{Abi} is + \tcode{\exposid{deduce-abi-t}}, + \item + otherwise, disabled, if \tcode{T} is not a vectorizable type, + \item + otherwise, it is \impldef{set of enabled \tcode{basic_simd} + specializations} if such a specialization is enabled. +\end{itemize} + +If \tcode{basic_simd} is disabled, then the specialization has a +deleted default constructor, deleted destructor, deleted copy constructor, and +deleted copy assignment. +In addition only the \tcode{value_type}, \tcode{abi_type}, and +\tcode{mask_type} members are present. + +If \tcode{basic_simd} is enabled, then \tcode{basic_simd} is +trivially copyable, default-initialization of an object of such a type +default-initializes all elements, and value-initialization value-initializes +all elements\iref{dcl.init.general}. + +\pnum +\recommended +Implementations should support implicit conversions between specializations of +\tcode{basic_simd} and appropriate \impldef{conversions of \tcode{basic_simd} +from/to implementation-specific vector types} types. +\begin{note} +Appropriate types are non-standard vector types which are available in the +implementation. +\end{note} + +\rSec3[simd.ctor]{\tcode{basic_simd} constructors} + +\begin{itemdecl} +template constexpr explicit(@\seebelow@) basic_simd(U&& value) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{From} denote the type \tcode{remove_cvref_t}. + +\pnum +\constraints +\tcode{value_type} satisfies \tcode{\libconcept{constructible_from}}. + +\pnum +\effects +Initializes each element to the value of the argument after conversion to +\tcode{value_type}. + +\pnum +\remarks +The expression inside \tcode{explicit} evaluates to \tcode{false} if and only if +\tcode{U} satisfies \tcode{\libconcept{convertible_to}}, and either +\begin{itemize} + \item + \tcode{From} is not an arithmetic type and does not satisfy + \exposconcept{constexpr-wrapper-like}, + \item + \tcode{From} is an arithmetic type and the conversion from \tcode{From} to + \tcode{value_type} is value-preserving\iref{simd.general}, or + \item + \tcode{From} satisfies \exposconcept{constexpr-wrapper-like}, + \tcode{remove_const_t} is an arithmetic type, and + \tcode{From::value} is representable by \tcode{value_type}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr explicit(@\seebelow@) basic_simd(const basic_simd& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{\exposid{simd-size-v} == size()} is \tcode{true}. + +\pnum +\effects +Initializes the $i^\text{th}$ element with \tcode{static_cast(x[$i$])} for +all $i$ in the range of \range{0}{size()}. + +\pnum +\remarks +The expression inside \tcode{explicit} evaluates to \tcode{true} if either +\begin{itemize} + \item + the conversion from \tcode{U} to \tcode{value_type} is not value-preserving, + or + \item + both \tcode{U} and \tcode{value_type} are integral types and the integer + conversion rank\iref{conv.rank} of \tcode{U} is greater than the integer + conversion rank of \tcode{value_type}, or + \item + both \tcode{U} and \tcode{value_type} are floating-point types and the + floating-point conversion rank\iref{conv.rank} of \tcode{U} is greater than + the floating-point conversion rank of \tcode{value_type}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template constexpr explicit basic_simd(G&& gen); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{From}$_i$ denote the type +\tcode{decltype(gen(integral_constant<\exposid{simd-size-type}, $i$>()))}. + +\pnum +\constraints +\tcode{From}$_i$ satisfies \tcode{\libconcept{convertible_to}} for all $i$ in +the range of \range{0}{size()}. +In addition, for all $i$ in the range of \range{0}{size()}, if \tcode{From}$_i$ +is an arithmetic type, conversion from \tcode{From}$_i$ to \tcode{value_type} +is value-preserving. + +\pnum +\effects +Initializes the $i^\text{th}$ element with +\tcode{static_cast(gen(integral_constant<\exposid{simd-\brk{}size-\brk{}type}, +i>()))} for all $i$ in the range of \range{0}{size()}. + +\pnum +\remarks +\tcode{gen} is invoked exactly once for each $i$, in increasing order of $i$. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr basic_simd(R&& r, flags = {}); +template + constexpr basic_simd(R&& r, const mask_type& mask, flags = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{mask} be \tcode{mask_type(true)} for the overload with no +\tcode{mask} parameter. + +\pnum +\constraints +\begin{itemize} +\item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and + \tcode{ranges::\libconcept{sized_range}}, +\item \tcode{ranges::size(r)} is a constant expression, and +\item \tcode{ranges::size(r)} is equal to \tcode{size()}. +\end{itemize} + +\pnum +\mandates +\begin{itemize} + \item + \tcode{ranges::range_value_t} is a vectorizable type, and + \item + if the template parameter pack \tcode{Flags} does not contain + \tcode{\exposid{convert-flag}}, then the conversion from + \tcode{ranges::range_value_t} to \tcode{value_type} is value-preserving. +\end{itemize} + +\pnum +\expects +\begin{itemize} + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{aligned-flag}}, \tcode{ranges::data(r)} points to + storage aligned by \tcode{alignment_v>}. + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{overaligned-flag}}, \tcode{ranges::data(r)} points to + storage aligned by \tcode{N}. +\end{itemize} + +\pnum +\effects +Initializes the $i^\text{th}$ element with \tcode{mask[$i$] ? +static_cast(\brk{}ranges::\brk{}data(r)[$i$]) : T()} for all $i$ in the +range of \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_simd(R&& r, Ts...) -> @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and + \tcode{ranges::\libconcept{sized_range}}, and +\item \tcode{ranges::size(r)} is a constant expression. +\end{itemize} + +\pnum +\remarks +The deduced type is equivalent to \tcode{simd, +ranges::size(r)>}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-floating-point}@ V> + constexpr explicit(@\seebelow@) + basic_simd(const V& reals, const V& imags = {}) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + \tcode{\exposconcept{simd-complex}} is modeled, and + \item + \tcode{V::size() == size()} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Initializes the $i^\text{th}$ element with \tcode{value_type(reals[$i$], +imags[$i$])} for all $i$ in the range \range{0}{size()}. + +\pnum +\remarks +The expression inside \tcode{explicit} evaluates to \tcode{false} if and only +if the floating-point conversion rank of \tcode{T::value_type} is greater than +or equal to the floating-point conversion rank of \tcode{V::value_type}. +\end{itemdescr} + +\rSec3[simd.subscr]{\tcode{basic_simd} subscript operator} + +\begin{itemdecl} +constexpr value_type operator[](@\exposid{simd-size-type}@ i) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i >= 0 \&\& i < size()} is \tcode{true}. + +\pnum +\returns +The value of the $i^\text{th}$ element. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\rSec3[simd.unary]{\tcode{basic_simd} unary operators} + +\pnum +Effects in [simd.unary] are applied as unary element-wise operations. + +\begin{itemdecl} +constexpr basic_simd& operator++() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (value_type a) \{ ++a; \}} is \tcode{true}. + +\pnum +\effects +Increments every element by one. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd operator++(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (value_type a) \{ a++; \}} is \tcode{true}. + +\pnum +\effects +Increments every element by one. + +\pnum +\returns +A copy of \tcode{*this} before incrementing. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd& operator--() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (value_type a) \{ --a; \}} is \tcode{true}. + +\pnum +\effects +Decrements every element by one. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd operator--(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (value_type a) \{ a--; \}} is \tcode{true}. + +\pnum +\effects +Decrements every element by one. + +\pnum +\returns +A copy of \tcode{*this} before decrementing. +\end{itemdescr} + +\begin{itemdecl} +constexpr mask_type operator!() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (const value_type a) \{ !a; \}} is \tcode{true}. + +\pnum +\returns +A \tcode{basic_simd_mask} object with the $i^\text{th}$ element set to +\tcode{!operator[]($i$)} for all $i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd operator~() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (const value_type a) \{ \~{}a; \}} is \tcode{true}. + +\pnum +\returns +A \tcode{basic_simd} object with the $i^\text{th}$ element set to +\tcode{\~{}operator[]($i$)} for all $i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd operator+() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (const value_type a) \{ +a; \}} is \tcode{true}. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\begin{itemdecl} +constexpr basic_simd operator-() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{requires (const value_type a) \{ -a; \}} is \tcode{true}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +\tcode{-operator[]($i$)} for all $i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\rSec2[simd.nonmembers]{\tcode{basic_simd} non-member operations} + +\rSec3[simd.binary]{\tcode{basic_simd} binary operators} + +\begin{itemdecl} +friend constexpr basic_simd operator+(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator-(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator*(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator/(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator%(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator&(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator|(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator^(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator<<(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd operator>>(const basic_simd& lhs, const basic_simd& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\constraints +\tcode{requires (value_type a, value_type b) \{ a \placeholder{op} b; \}} is +\tcode{true}. + +\pnum +\returns +A \tcode{basic_simd} object initialized with the results of applying +\placeholder{op} to \tcode{lhs} and \tcode{rhs} as a binary element-wise +operation. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr basic_simd operator<<(const basic_simd& v, @\exposid{simd-size-type}@ n) noexcept; +friend constexpr basic_simd operator>>(const basic_simd& v, @\exposid{simd-size-type}@ n) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\constraints +\tcode{requires (value_type a, \exposid{simd-size-type} b) \{ a +\placeholder{op} b; \}} is \tcode{true}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of applying \placeholder{op} to \tcode{v[$i$]} and \tcode{n} for all +$i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\rSec3[simd.cassign]{\tcode{basic_simd} compound assignment} + +\begin{itemdecl} +friend constexpr basic_simd& operator+=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator-=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator*=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator/=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator%=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator&=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator|=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator^=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator<<=(basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr basic_simd& operator>>=(basic_simd& lhs, const basic_simd& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\constraints +\tcode{requires (value_type a, value_type b) \{ a \placeholder{op} b; \}} is +\tcode{true}. + +\pnum +\effects +These operators apply the indicated operator to \tcode{lhs} and \tcode{rhs} as +an element-wise operation. + +\pnum +\returns +\tcode{lhs}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr basic_simd& operator<<=(basic_simd& lhs, @\exposid{simd-size-type}@ n) noexcept; +friend constexpr basic_simd& operator>>=(basic_simd& lhs, @\exposid{simd-size-type}@ n) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\constraints +\tcode{requires (value_type a, \exposid{simd-size-type} b) \{ a +\placeholder{op} b; \}} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return operator \placeholder{op} (lhs, basic_simd(n));} +\end{itemdescr} + +\rSec3[simd.comparison]{\tcode{basic_simd} compare operators} + +\begin{itemdecl} +friend constexpr mask_type operator==(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr mask_type operator!=(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr mask_type operator>=(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr mask_type operator<=(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr mask_type operator>(const basic_simd& lhs, const basic_simd& rhs) noexcept; +friend constexpr mask_type operator<(const basic_simd& lhs, const basic_simd& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\constraints +\tcode{requires (value_type a, value_type b) \{ a \placeholder{op} b; \}} is +\tcode{true}. + +\pnum +\returns +A \tcode{basic_simd_mask} object initialized with the results of applying +\placeholder{op} to \tcode{lhs} and \tcode{rhs} as a binary element-wise +operation. +\end{itemdescr} + +\rSec3[simd.complex.access]{\tcode{simd} complex accessors} + +\begin{itemdecl} +constexpr auto real() const noexcept; +constexpr auto imag() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{\exposconcept{simd-complex}} is modeled. + +\pnum +\returns +An object of type \tcode{rebind_t} +where the $i^\text{th}$ element is initialized to the result of +\tcode{\placeholder{cmplx-func}(operator[]($i$))} for all $i$ in the range +\range{0}{size()}, where \placeholder{cmplx-func} is the corresponding function +from \libheader{complex}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-floating-point}@ V> + constexpr void real(const V& v) noexcept; +template<@\exposconcept{simd-floating-point}@ V> + constexpr void imag(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + \tcode{\exposconcept{simd-complex}} is modeled, + \item + \tcode{\libconcept{same_as}} + is modeled, and + \item + \tcode{V::size() == size()} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Replaces each element of the \tcode{basic_simd} object such that the +$i^\text{th}$ element is replaced with \tcode{value_type(v[$i$], +operator[]($i$).imag())} or \tcode{value_type(operator[]($i$).real(), v[$i$])} +for \tcode{real} and \tcode{imag} respectively, for all $i$ in the range \range{0}{size()}. +\end{itemdescr} + +\rSec3[simd.cond]{\tcode{basic_simd} exposition only conditional operators} + +\begin{itemdecl} +friend constexpr basic_simd +@\exposid{simd-select-impl}@(const mask_type& mask, const basic_simd& a, const basic_simd& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element equals +\tcode{mask[$i$] ? a[$i$] : b[$i$]} for all $i$ in the range of +\range{0}{size()}. +\end{itemdescr} + +\rSec3[simd.reductions]{\tcode{basic_simd} reductions} + +\begin{itemdecl} +template> + constexpr T reduce(const basic_simd& x, BinaryOperation binary_op = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{BinaryOperation} models +\tcode{\exposconcept{reduction-binary-operation}}. + +\pnum +\expects +\tcode{binary_op} does not modify \tcode{x}. + +\pnum +\returns +\tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, simd(x[0]), $\ldots$, +simd(x[x.size() - 1])\brk{})[0]}\iref{numerics.defns}. + +\pnum +\throws +Any exception thrown from \tcode{binary_op}. +\end{itemdescr} + +\begin{itemdecl} +template> + constexpr T reduce( + const basic_simd& x, const typename basic_simd::mask_type& mask, + BinaryOperation binary_op = {}, type_identity_t identity_element = @\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item + \tcode{BinaryOperation} models + \tcode{\exposconcept{reduction-binary-operation}}. +\item + An argument for \tcode{identity_element} is provided for the invocation, + unless \tcode{BinaryOperation} is one of \tcode{plus<>}, + \tcode{multiplies<>}, \tcode{bit_and<>}, \tcode{bit_or<>}, or + \tcode{bit_xor<>}. +\end{itemize} + +\pnum +\expects +\begin{itemize} + \item + \tcode{binary_op} does not modify \tcode{x}. + \item + For all finite values \tcode{y} representable by \tcode{T}, the results of + \tcode{y == binary_op(simd(iden\-ti\-ty\-_\-element), simd(y))[0]} and \tcode{y == binary_op(simd(y), simd(iden\-ti\-ty\-_\-element))[0]} are \tcode{true}. +\end{itemize} + +\pnum +\returns +If \tcode{none_of(mask)} is \tcode{true}, returns \tcode{identity_element}. +Otherwise, returns \tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, simd(x[$k_0$]), $\ldots$, simd(x[$k_n$]))[0]} where $k_0, \ldots, k_n$ are +the selected indices of \tcode{mask}. + +\pnum +\throws +Any exception thrown from \tcode{binary_op}. + +\pnum +\remarks +The default argument for \tcode{identity_element} is equal to +\begin{itemize} +\item \tcode{T()} if \tcode{BinaryOperation} is \tcode{plus<>}, +\item \tcode{T(1)} if \tcode{BinaryOperation} is \tcode{multiplies<>}, +\item \tcode{T(\~{}T())} if \tcode{BinaryOperation} is \tcode{bit_and<>}, +\item \tcode{T()} if \tcode{BinaryOperation} is \tcode{bit_or<>}, or +\item \tcode{T()} if \tcode{BinaryOperation} is \tcode{bit_xor<>}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template constexpr T reduce_min(const basic_simd& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +The value of an element \tcode{x[$j$]} for which \tcode{x[$i$] < x[$j$]} is +\tcode{false} for all $i$ in the range of \range{0}{basic_simd::size()}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr T reduce_min( + const basic_simd&, const typename basic_simd::mask_type&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +If \tcode{none_of(mask)} is \tcode{true}, returns +\tcode{numeric_limits::max()}. +Otherwise, returns the value of a selected element \tcode{x[$j$]} for which +\tcode{x[$i$] < x[$j$]} is \tcode{false} for all selected indices $i$ of +\tcode{mask}. +\end{itemdescr} + +\begin{itemdecl} +template constexpr T reduce_max(const basic_simd& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +The value of an element \tcode{x[$j$]} for which \tcode{x[$j$] < x[$i$]} is +\tcode{false} for all $i$ in the range of \range{0}{basic_simd::size()}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr T reduce_max( + const basic_simd&, const typename basic_simd::mask_type&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +If \tcode{none_of(mask)} is \tcode{true}, returns +\tcode{numeric_limits::lowest()}. +Otherwise, returns the value of a selected element \tcode{x[$j$]} for which +\tcode{x[$j$] < x[$i$]} is \tcode{false} for all selected indices $i$ of +\tcode{mask}. +\end{itemdescr} + +\rSec3[simd.loadstore]{\tcode{basic_simd} load and store functions} + +\begin{itemdecl} +template + requires ranges::@\libconcept{sized_range}@ + constexpr V unchecked_load(R&& r, flags f = {}); +template + requires ranges::@\libconcept{sized_range}@ + constexpr V unchecked_load(R&& r, const typename V::mask_type& mask, flags f = {}); +template + constexpr V unchecked_load(I first, iter_difference_t n, flags f = {}); +template + constexpr V unchecked_load(I first, iter_difference_t n, const typename V::mask_type& mask, + flags f = {}); +template S, class... Flags> + constexpr V unchecked_load(I first, S last, flags f = {}); +template S, class... Flags> + constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask, + flags f = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} + \item + \tcode{mask} be \tcode{V::mask_type(true)} for the overloads with no + \tcode{mask} parameter; + \item + \tcode{R} be \tcode{span>} for the overloads with no + template parameter \tcode{R}; + \item + \tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n} + parameter and \tcode{R(first, last)} for the overloads with a \tcode{last} + parameter. +\end{itemize} + +\pnum +\mandates +If \tcode{ranges::size(r)} is a constant expression then +\tcode{ranges::size(r)} $\ge$ \tcode{V::size()}. + +\pnum +\expects +\begin{itemize} +\item \range{first}{first + n} is a valid range for the overloads with an + \tcode{n} parameter. +\item \range{first}{last} is a valid range for the overloads with a + \tcode{last} parameter. +\item \tcode{ranges::size(r)} $\ge$ \tcode{V::size()} +\end{itemize} + +\pnum +\effects +Equivalent to: \tcode{return partial_load(r, mask, f);} + +\pnum +\remarks +The default argument for template parameter \tcode{V} is +\tcode{basic_simd>}. +\end{itemdescr} + +\begin{itemdecl} +template + requires ranges::@\libconcept{sized_range}@ + constexpr V partial_load(R&& r, flags f = {}); +template + requires ranges::@\libconcept{sized_range}@ + constexpr V partial_load(R&& r, const typename V::mask_type& mask, flags f = {}); +template + constexpr V partial_load(I first, iter_difference_t n, flags f = {}); +template + constexpr V partial_load(I first, iter_difference_t n, const typename V::mask_type& mask, + flags f = {}); +template S, class... Flags> + constexpr V partial_load(I first, S last, flags f = {}); +template S, class... Flags> + constexpr V partial_load(I first, S last, const typename V::mask_type& mask, + flags f = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} + \item + \tcode{mask} be \tcode{V::mask_type(true)} for the overloads with no + \tcode{mask} parameter; + \item + \tcode{R} be \tcode{span>} for the overloads with no + template parameter \tcode{R}; + \item + \tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n} + parameter and \tcode{R(first, last)} for the overloads with a \tcode{last} + parameter. +\end{itemize} + +\pnum +\mandates +\begin{itemize} + \item + \tcode{ranges::range_value_t} is a vectorizable type, + \item + \tcode{same_as, V>} is \tcode{true}, + \item + \tcode{V} is an enabled specialization of \tcode{basic_simd}, and + \item + if the template parameter pack \tcode{Flags} does not contain + \tcode{\exposid{convert-flag}}, then the conversion from + \tcode{ranges::range_value_t} to \tcode{V::value_type} is + value-preserving. +\end{itemize} + +\pnum +\expects +\begin{itemize} + \item + \range{first}{first + n} is a valid range for the overloads with an + \tcode{n} parameter. + \item + \range{first}{last} is a valid range for the overloads with a \tcode{last} + parameter. + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{aligned-flag}}, \tcode{ranges::data(r)} points to storage + aligned by \tcode{alignment_v>}. + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{overaligned-flag}}, \tcode{ranges::data(r)} points to + storage aligned by \tcode{N}. +\end{itemize} + +\pnum +\effects +Initializes the $i^\text{th}$ element with\\ +\tcode{mask[$i$] \&\& $i$ < ranges::size(r) ? +static_cast(\brk{}ranges::data(r)[$i$]) : T()} for all $i$ in the range of +\range{0}{V::size()}. + +\pnum +\remarks +The default argument for template parameter \tcode{V} is +\tcode{basic_simd>}. +\end{itemdescr} + +\begin{itemdecl} +template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void unchecked_store(const basic_simd& v, R&& r, flags f = {}); +template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void unchecked_store(const basic_simd& v, R&& r, + const typename basic_simd::mask_type& mask, flags f = {}); +template + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, iter_difference_t n, + flags f = {}); +template + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, iter_difference_t n, + const typename basic_simd::mask_type& mask, flags f = {}); +template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, S last, + flags f = {}); +template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void unchecked_store(const basic_simd& v, I first, S last, + const typename basic_simd::mask_type& mask, flags f = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} + \item + \tcode{mask} be \tcode{basic_simd::mask_type(true)} for the + overloads with no \tcode{mask} parameter; + \item + \tcode{R} be \tcode{span>} for the overloads with no + template parameter \tcode{R}; + \item + \tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n} + parameter and \tcode{R(first, last)} for the overloads with a \tcode{last} + parameter. +\end{itemize} + +\pnum +\mandates +If \tcode{ranges::size(r)} is a constant expression then +\tcode{ranges::size(r)} $\ge$ \tcode{\exposid{simd-size-v}}. + +\pnum +\expects +\begin{itemize} + \item + \range{first}{first + n} is a valid range for the overloads with an + \tcode{n} parameter. + \item + \range{first}{last} is a valid range for the overloads with a \tcode{last} + parameter. + \item + \tcode{ranges::size(r)} $\ge$ \tcode{\exposid{simd-size-v}} +\end{itemize} + +\pnum +\effects +Equivalent to: \tcode{partial_store(v, r, mask, f)}. +\end{itemdescr} + +\begin{itemdecl} +template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void partial_store(const basic_simd& v, R&& r, flags f = {}); +template + requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + constexpr void partial_store(const basic_simd& v, R&& r, + const typename basic_simd::mask_type& mask, flags f = {}); +template + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, iter_difference_t n, + flags f = {}); +template + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, iter_difference_t n, + const typename basic_simd::mask_type& mask, flags f = {}); +template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, S last, + flags f = {}); +template S, class... Flags> + requires @\libconcept{indirectly_writable}@ + constexpr void partial_store(const basic_simd& v, I first, S last, + const typename basic_simd::mask_type& mask, flags f = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} + \item + \tcode{mask} be \tcode{basic_simd::mask_type(true)} for the + overloads with no \tcode{mask} parameter; + \item + \tcode{R} be \tcode{span>} for the overloads with no + template parameter \tcode{R}; + \item + \tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n} + parameter and \tcode{R(first, last)} for the overloads with a \tcode{last} + parameter. +\end{itemize} + +\pnum +\mandates +\begin{itemize} + \item + \tcode{ranges::range_value_t} is a vectorizable type, and + \item + if the template parameter pack \tcode{Flags} does not contain + \tcode{\exposid{convert-flag}}, then the conversion from \tcode{T} to + \tcode{ranges::range_value_t} is value-preserving. +\end{itemize} + +\pnum +\expects +\begin{itemize} + \item + \range{first}{first + n} is a valid range for the overloads with an + \tcode{n} parameter. + \item + \range{first}{last} is a valid range for the overloads with a \tcode{last} + parameter. + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{aligned-flag}}, \tcode{ranges::data(r)} points to storage + aligned by \tcode{alignment_v, + ranges::range_value_t>}. + \item + If the template parameter pack \tcode{Flags} contains + \tcode{\exposid{overaligned-flag}}, \tcode{ranges::data(r)} points to + storage aligned by \tcode{N}. +\end{itemize} + +\pnum +\effects +For all $i$ in the range of \range{0}{basic_simd::size()}, if +\tcode{mask[$i$] \&\& $i$ < ranges::\brk{}size(r)} is \tcode{true}, evaluates +\tcode{ranges::data(r)[$i$] = v[$i$]}. +\end{itemdescr} + +\rSec3[simd.creation]{\tcode{basic_simd} and \tcode{basic_simd_mask} creation} + +\begin{itemdecl} +template + constexpr auto chunk(const basic_simd& x) noexcept; +template + constexpr auto chunk(const basic_simd_mask<@\exposid{mask-element-size}@, Abi>& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + For the first overload \tcode{T} is an enabled specialization of + \tcode{basic_simd}. + If \tcode{basic_simd<\brk{}typename T::\brk{}value_type, Abi>::size() \% + T::size()} is not \tcode{0} then + \tcode{resize_t::size() + \% T::size(), T>} is valid and denotes a type. + + \item + For the second overload \tcode{T} is an enabled specialization of + \tcode{basic_simd\-_\-mask}. + If \tcode{basic_simd_mask<\exposid{mask-element-size}, Abi>::size() \% + T::size()} is not \tcode{0} then + \tcode{resize_t<\brk{}ba\-sic\-_\-simd_mask<\brk{}\exposid{mask-element-size}, + Abi>::size() \% T::size(), T>} is valid and denotes a type. +\end{itemize} + +\pnum +Let $N$ be \tcode{x.size() / T::size()}. + +\pnum +\returns +\begin{itemize} + \item + If \tcode{x.size() \% T::size() == 0} is \tcode{true}, an \tcode{array} with the $i^\text{th}$ \tcode{basic_simd} or \tcode{basic_simd_mask} + element of the $j^\text{th}$ \tcode{array} element initialized to the value + of the element in \tcode{x} with index \tcode{$i$ + $j$ * T::size()}. + + \item + Otherwise, a \tcode{tuple} of $N$ objects of type \tcode{T} and one object + of type \tcode{resize_t}. + The $i^\text{th}$ \tcode{basic_simd} or \tcode{basic_simd_mask} element of + the $j^\text{th}$ \tcode{tuple} element of type \tcode{T} is initialized to + the value of the element in \tcode{x} with index \tcode{$i$ + $j$ * + T::size()}. + The $i^\text{th}$ \tcode{basic_simd} or \tcode{basic_simd_mask} element of + the $N^\text{th}$ \tcode{tuple} element is initialized to the value of the + element in \tcode{x} with index \tcode{$i$ + $N$ * T::size()}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto chunk(const basic_simd& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return chunk>>(x);} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto chunk(const basic_simd_mask& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return chunk>>(x);} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr simd::size() + ...)> + cat(const basic_simd&... xs) noexcept; +template + constexpr basic_simd_mask, + (basic_simd_mask::size() + ...)>> + cat(const basic_simd_mask&... xs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + For the first overload \tcode{simd::size() + ...)>} + is enabled. + \item + For the second overload + \tcode{basic_simd_mask, + (ba\-sic_simd_mask::size() + ...)>>} is enabled. +\end{itemize} + +\pnum +\returns +A data-parallel object initialized with the concatenated values in the +\tcode{xs} pack of data-parallel objects: The $i^\text{th}$ +\tcode{basic_simd}/\tcode{basic_simd_mask} element of the $j^\text{th}$ +parameter in the \tcode{xs} pack is copied to the return value's element with +index $i$ + the sum of the width of the first $j$ parameters in the \tcode{xs} +pack. +\end{itemdescr} + +\rSec3[simd.alg]{Algorithms} + +\begin{itemdecl} +template + constexpr basic_simd min(const basic_simd& a, + const basic_simd& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +The result of the element-wise application of \tcode{min(a[$i$], b[$i$])} for +all $i$ in the range of \range{0}{basic_simd::size()}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr basic_simd max(const basic_simd& a, + const basic_simd& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\returns +The result of the element-wise application of \tcode{max(a[$i$], b[$i$])} for +all $i$ in the range of \range{0}{basic_simd::size()}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr pair, basic_simd> + minmax(const basic_simd& a, const basic_simd& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return pair\{min(a, b), max(a, b)\};} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr basic_simd clamp( + const basic_simd& v, const basic_simd& lo, const basic_simd& hi); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} models \tcode{totally_ordered}. + +\pnum +\expects +No element in \tcode{lo} shall be greater than the corresponding element in +\tcode{hi}. + +\pnum +\returns +The result of element-wise application of \tcode{clamp(v[$i$], lo[$i$], +hi[$i$])} for all $i$ in the range of \range{0}{basic_simd::size()}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto select(bool c, const T& a, const U& b) + -> remove_cvref_t; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return c ? a : b;} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto select(const basic_simd_mask& c, const T& a, const U& b) + noexcept -> decltype(@\exposid{simd-select-impl}@(c, a, b)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{simd-select-impl}@(c, a, b); +\end{codeblock} +where \tcode{\exposid{simd-select-impl}} is found by argument-dependent +lookup\iref{basic.lookup.argdep} contrary to \ref{contents}. +\end{itemdescr} + +\rSec3[simd.math]{Mathematical functions} + +\begin{itemdecl} +template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> ilogb(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ ldexp(const V& x, const rebind_t>& exp); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ scalbn(const V& x, const rebind_t>& n); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ + scalbln(const V& x, const rebind_t>& n); +template<@\libconcept{signed_integral}@ T, class Abi> + constexpr basic_simd abs(const basic_simd& j); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ abs(const V& j); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ fabs(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ ceil(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ floor(const V& x); +template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ nearbyint(const V& x); +template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ rint(const V& x); +template<@\exposconcept{math-floating-point}@ V> + rebind_t> lrint(const V& x); +template<@\exposconcept{math-floating-point}@ V> + rebind_t> llrint(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ round(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> lround(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> llround(const V& x); +template + constexpr @\exposid{math-common-simd-t}@ fmod(const V0& x, const V1& y); +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ trunc(const V& x); +template + constexpr @\exposid{math-common-simd-t}@ remainder(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ copysign(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ nextafter(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ fdim(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ fmax(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ fmin(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ fma(const V0& x, const V1& y, const V2& z); +template<@\exposconcept{math-floating-point}@ V> + constexpr rebind_t> fpclassify(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isfinite(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isinf(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isnan(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type isnormal(const V& x); +template<@\exposconcept{math-floating-point}@ V> + constexpr typename @\exposid{deduced-simd-t}@::mask_type signbit(const V& x); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type isgreater(const V0& x, const V1& y); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type + isgreaterequal(const V0& x, const V1& y); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type isless(const V0& x, const V1& y); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type islessequal(const V0& x, const V1& y); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type islessgreater(const V0& x, const V1& y); +template + constexpr typename @\exposid{math-common-simd-t}@::mask_type isunordered(const V0& x, const V1& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Ret} denote the return type of the specialization of a function +template with the name \placeholder{math-func}. +Let \placeholder{math-func-simd} denote: +\begin{codeblock} +template +Ret @\placeholder{math-func-simd}@(Args... args) { + return Ret([&](@\exposid{simd-size-type}@ i) { + @\placeholder{math-func}@(@\exposid{make-compatible-simd-t}@(args)[i]...); + }); +} +\end{codeblock} + +\pnum +\returns +A value \tcode{ret} of type \tcode{Ret}, that is element-wise equal to the +result of calling \placeholder{math-func-simd} with the arguments of the above +functions. +If in an invocation of a scalar overload of \placeholder{math-func} for index +\tcode{i} in \placeholder{math-func-simd} a domain, pole, or range error would +occur, the value of \tcode{ret[i]} is unspecified. + +\pnum +\remarks +It is unspecified whether \tcode{errno}\iref{errno} is accessed. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ acos(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ asin(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ atan(const V& x); +template + constexpr @\exposid{math-common-simd-t}@ atan2(const V0& y, const V1& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cos(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sin(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tan(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ acosh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ asinh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ atanh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cosh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sinh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tanh(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ exp(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ exp2(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ expm1(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log10(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log1p(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ log2(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ logb(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ cbrt(const V& x); +template + constexpr @\exposid{math-common-simd-t}@ hypot(const V0& x, const V1& y); +template + constexpr @\exposid{math-common-simd-t}@ hypot(const V0& x, const V1& y, const V2& z); +template + constexpr @\exposid{math-common-simd-t}@ pow(const V0& x, const V1& y); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ sqrt(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ erf(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ erfc(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ lgamma(const V& x); +template<@\exposconcept{math-floating-point}@ V> constexpr @\exposid{deduced-simd-t}@ tgamma(const V& x); +template + constexpr @\exposid{math-common-simd-t}@ lerp(const V0& a, const V1& b, const V2& t) noexcept; +template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ assoc_laguerre(const rebind_t>& n, const + rebind_t>& m, + const V& x); +template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ assoc_legendre(const rebind_t>& l, const + rebind_t>& m, + const V& x); +template + @\exposid{math-common-simd-t}@ beta(const V0& x, const V1& y); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ comp_ellint_1(const V& k); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ comp_ellint_2(const V& k); +template + @\exposid{math-common-simd-t}@ comp_ellint_3(const V0& k, const V1& nu); +template + @\exposid{math-common-simd-t}@ cyl_bessel_i(const V0& nu, const V1& x); +template + @\exposid{math-common-simd-t}@ cyl_bessel_j(const V0& nu, const V1& x); +template + @\exposid{math-common-simd-t}@ cyl_bessel_k(const V0& nu, const V1& x); +template + @\exposid{math-common-simd-t}@ cyl_neumann(const V0& nu, const V1& x); +template + @\exposid{math-common-simd-t}@ ellint_1(const V0& k, const V1& phi); +template + @\exposid{math-common-simd-t}@ ellint_2(const V0& k, const V1& phi); +template + @\exposid{math-common-simd-t}@ ellint_3(const V0& k, const V1& nu, const V2& phi); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ expint(const V& x); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ hermite(const rebind_t>& n, const V& x); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ laguerre(const rebind_t>& n, const V& x); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ legendre(const rebind_t>& l, const V& x); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ riemann_zeta(const V& x); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ sph_bessel(const rebind_t>& n, const V& x); +template<@\exposconcept{math-floating-point}@ V> + @\exposid{deduced-simd-t}@ sph_legendre(const rebind_t>& l, + const rebind_t>& m, + const V& theta); +template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ sph_neumann(const rebind_t>& n, const V& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Ret} denote the return type of the specialization of a function +template with the name \placeholder{math-func}. +Let \placeholder{math-func-simd} denote: +\begin{codeblock} +template +Ret @\placeholder{math-func-simd}@(Args... args) { + return Ret([&](@\exposid{simd-size-type}@ i) { + @\placeholder{math-func}@(@\exposid{make-compatible-simd-t}@(args)[i]...); + }); +} +\end{codeblock} + +\pnum +\returns +A value \tcode{ret} of type \tcode{Ret}, that is element-wise approximately +equal to the result of calling \placeholder{math-func-simd} with the arguments +of the above functions. +If in an invocation of a scalar overload of \placeholder{math-func} for index +\tcode{i} in \placeholder{math-func-simd} a domain, pole, or range error would +occur, the value of \tcode{ret[i]} is unspecified. + +\pnum +\remarks +It is unspecified whether \tcode{errno}\iref{errno} is accessed. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{math-floating-point}@ V> + constexpr @\exposid{deduced-simd-t}@ frexp(const V& value, rebind_t>* exp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Ret} be \tcode{\exposid{deduced-simd-t}}. +Let \placeholder{frexp-simd} denote: +\begin{codeblock} +template +pair> @\placeholder{frexp-simd}@(const V& x) { + int r1[Ret::size()]; + Ret r0([&](@\exposid{simd-size-type}@ i) { + frexp(@\exposid{make-compatible-simd-t}@(x)[i], &r1[i]); + }); + return {r0, rebind_t(r1)}; +} +\end{codeblock} +Let \tcode{ret} be a value of type \tcode{pair>} +that is the same value as the result of calling +\placeholder{frexp-simd}\tcode{(x)}. + +\pnum +\effects +Sets \tcode{*exp} to \tcode{ret.second}. + +\pnum +\returns +\tcode{ret.first}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr @\exposid{math-common-simd-t}@ remquo(const V0& x, const V1& y, + rebind_t>* quo); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Ret} be \tcode{\exposid{math-common-simd-t}}. +Let \placeholder{remquo-simd} denote: +\begin{codeblock} +template +pair> @\placeholder{remquo-simd}@(const V0& x, const V1& y) { + int r1[Ret::size()]; + Ret r0([&](@\exposid{simd-size-type}@ i) { + remquo(@\exposid{make-compatible-simd-t}@(x)[i], + @\exposid{make-compatible-simd-t}@(y)[i], &r1[i]); + }); + return {r0, rebind_t(r1)}; +} +\end{codeblock} +Let \tcode{ret} be a value of type \tcode{pair>} +that is the same value as the result of calling +\placeholder{remquo-simd}\tcode{(x, y)}. +If in an invocation of a scalar overload of \tcode{remquo} for index \tcode{i} +in \placeholder{remquo-simd} a domain, pole, or range error would occur, the +value of \tcode{ret[i]} is unspecified. + +\pnum +\effects +Sets \tcode{*quo} to \tcode{ret.second}. + +\pnum +\returns +\tcode{ret.first}. + +\pnum +\remarks +It is unspecified whether \tcode{errno}\iref{errno} is accessed. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr basic_simd modf(const type_identity_t>& value, + basic_simd* iptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{V} be \tcode{basic_simd}. +Let \placeholder{modf-simd} denote: +\begin{codeblock} +pair @\placeholder{modf-simd}@(const V& x) { + T r1[Ret::size()]; + V r0([&](@\exposid{simd-size-type}@ i) { + modf(V(x)[i], &r1[i]); + }); + return {r0, V(r1)}; +} +\end{codeblock} +Let \tcode{ret} be a value of type \tcode{pair} that is the same value as +the result of calling \placeholder{modf-simd}\tcode{(value)}. + +\pnum +\effects +Sets \tcode{*iptr} to \tcode{ret.second}. + +\pnum +\returns +\tcode{ret.first}. +\end{itemdescr} + +\rSec3[simd.bit]{\tcode{basic_simd} bit library} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} models \tcode{integral}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::byteswap(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\expects +For every $i$ in the range \range{0}{V::size()}, the smallest power of 2 +greater than or equal to \tcode{v[$i$]} is representable as a value of type +\tcode{V::value_type}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::bit_ceil(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. + +\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} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::bit_floor(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> + constexpr typename V::mask_type has_single_bit(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +A \tcode{basic_simd_mask} object where the $i^\text{th}$ element is initialized +to the result of \tcode{std::has_single_bit(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotl(const V0& v0, const V1& v1) noexcept; +template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotr(const V0& v0, const V1& v1) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + The type \tcode{V0::value_type} is an unsigned integer type\iref{basic.fundamental}, + \item + the type \tcode{V1::value_type} models \tcode{integral}, + \item + \tcode{V0::size() == V1::size()} is \tcode{true}, and + \item + \tcode{sizeof(typename V0::value_type) == sizeof(typename V1::value_type)} is \tcode{true}. +\end{itemize} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v0[$i$], +static_cast(v1[$i$]))} for all $i$ in the range \range{0}{V0::size()}, +where \placeholder{bit-func} is the corresponding scalar function from \libheader{bit}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V rotl(const V& v, int s) noexcept; +template<@\exposconcept{simd-type}@ V> constexpr V rotr(const V& v, int s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v[$i$], s)} for all $i$ in the +range \range{0}{V::size()}, where \placeholder{bit-func} is the corresponding +scalar function from \libheader{bit}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> bit_width(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countl_zero(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countl_one(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countr_zero(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> countr_one(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_t, V> popcount(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v[$i$])} for all $i$ in the range +\range{0}{V::size()}, where \placeholder{bit-func} is the corresponding scalar +function from \libheader{bit}. +\end{itemdescr} + +\rSec3[simd.complex.math]{\tcode{simd} complex math} + +\begin{itemdecl} +template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> real(const V&) noexcept; +template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> imag(const V&) noexcept; + +template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> abs(const V&); +template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> arg(const V&); +template<@\exposconcept{simd-complex}@ V> + constexpr rebind_t<@\exposid{simd-complex-value-type}@, V> norm(const V&); +template<@\exposconcept{simd-complex}@ V> constexpr V conj(const V&); +template<@\exposconcept{simd-complex}@ V> constexpr V proj(const V&); + +template<@\exposconcept{simd-complex}@ V> constexpr V exp(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V log(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V log10(const V& v); + +template<@\exposconcept{simd-complex}@ V> constexpr V sqrt(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V sin(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V asin(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V cos(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V acos(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V tan(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V atan(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V sinh(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V asinh(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V cosh(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V acosh(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V tanh(const V& v); +template<@\exposconcept{simd-complex}@ V> constexpr V atanh(const V& v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_simd} object \tcode{ret} where the $i^\text{th}$ element is +initialized to the result of \tcode{\placeholder{cmplx-func}(v[$i$])} for all +$i$ in the range \range{0}{V::size()}, where \placeholder{cmplx-func} is the +corresponding function from \libheader{complex}. If in an invocation of +\placeholder{cmplx-func} for index $i$ a domain, pole, or range error would +occur, the value of \tcode{ret[$i$]} is unspecified. + +\pnum +\remarks +It is unspecified whether \tcode{errno}\iref{errno} is accessed. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-floating-point}@ V> + rebind_t, V> polar(const V& x, const V& y = {}); + +template<@\exposconcept{simd-complex}@ V> constexpr V pow(const V& x, const V& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_simd} object \tcode{ret} where the $i^\text{th}$ element is +initialized to the result of \tcode{\placeholder{cmplx-func}(x[$i$], y[$i$])} +for all $i$ in the range \range{0}{V::size()}, where \placeholder{cmplx-func} +is the corresponding function from \libheader{complex}. If in an invocation of +\placeholder{cmplx-func} for index $i$ a domain, pole, or range error would +occur, the value of \tcode{ret[$i$]} is unspecified. + +\pnum +\remarks +It is unspecified whether \tcode{errno}\iref{errno} is accessed. +\end{itemdescr} + +\rSec2[simd.mask.class]{Class template \tcode{basic_simd_mask}} + +\rSec3[simd.mask.overview]{Class template \tcode{basic_simd_mask} overview} + +\begin{codeblock} +namespace std::datapar { + template class basic_simd_mask { + public: + using value_type = bool; + using abi_type = Abi; + + static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@<@\exposid{integer-from}@, Abi>> + size {}; + + constexpr basic_simd_mask() noexcept = default; + + // \ref{simd.mask.ctor}, \tcode{basic_simd_mask} constructors + constexpr explicit basic_simd_mask(value_type) noexcept; + template + constexpr explicit basic_simd_mask(const basic_simd_mask&) noexcept; + template constexpr explicit basic_simd_mask(G&& gen) noexcept; + + // \ref{simd.mask.subscr}, \tcode{basic_simd_mask} subscript operators + constexpr value_type operator[](@\exposid{simd-size-type}@) const; + + // \ref{simd.mask.unary}, \tcode{basic_simd_mask} unary operators + constexpr basic_simd_mask operator!() const noexcept; + constexpr basic_simd<@\exposid{integer-from}@, Abi> operator+() const noexcept; + constexpr basic_simd<@\exposid{integer-from}@, Abi> operator-() const noexcept; + constexpr basic_simd<@\exposid{integer-from}@, Abi> operator~() const noexcept; + + // \ref{simd.mask.conv}, \tcode{basic_simd_mask} conversion operators + template + constexpr explicit(sizeof(U) != Bytes) operator basic_simd() const noexcept; + + // \ref{simd.mask.binary}, \tcode{basic_simd_mask} binary operators + friend constexpr basic_simd_mask + operator&&(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator||(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator&(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator|(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator^(const basic_simd_mask&, const basic_simd_mask&) noexcept; + + // \ref{simd.mask.cassign}, \tcode{basic_simd_mask} compound assignment + friend constexpr basic_simd_mask& + operator&=(basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask& + operator|=(basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask& + operator^=(basic_simd_mask&, const basic_simd_mask&) noexcept; + + // \ref{simd.mask.comparison}, \tcode{basic_simd_mask} comparisons + friend constexpr basic_simd_mask + operator==(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator!=(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator>=(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator<=(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator>(const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask + operator<(const basic_simd_mask&, const basic_simd_mask&) noexcept; + + // \ref{simd.mask.cond}, \tcode{basic_simd_mask} exposition only conditional operators + friend constexpr basic_simd_mask @\exposid{simd-select-impl}@( // \expos + const basic_simd_mask&, const basic_simd_mask&, const basic_simd_mask&) noexcept; + friend constexpr basic_simd_mask @\exposid{simd-select-impl}@( // \expos + const basic_simd_mask&, @\libconcept{same_as}@ auto, @\libconcept{same_as}@ auto) noexcept; + template + friend constexpr simd<@\seebelow@, size()> + @\exposid{simd-select-impl}@(const basic_simd_mask&, const T0&, const T1&) noexcept; // \expos + }; +} +\end{codeblock} + +\pnum +Every specialization of \tcode{basic_simd_mask} is a complete type. +The specialization of \tcode{basic_simd_mask} is: +\begin{itemize} + \item + disabled, if there is no vectorizable type \tcode{T} such that \tcode{Bytes} + is equal to \tcode{sizeof(T)}, + \item + otherwise, enabled, if there exists a vectorizable type \tcode{T} and a + value \tcode{N} in the range \crange{1}{64} such that \tcode{Bytes} is equal + to \tcode{sizeof(T)} and \tcode{Abi} is \tcode{\exposid{deduce-abi-t}}, + \item + otherwise, it is \impldef{set of enabled \tcode{basic_simd_mask} + specializations} if such a specialization is enabled. +\end{itemize} + +If \tcode{basic_simd_mask} is disabled, the specialization has a +deleted default constructor, deleted destructor, deleted copy constructor, and +deleted copy assignment. +In addition only the \tcode{value_type} and \tcode{abi_type} members are +present. + +If \tcode{basic_simd_mask} is enabled, +\tcode{basic_simd_mask} is trivially copyable. + +\pnum +\recommended Implementations should support implicit conversions between +specializations of \tcode{basic_simd_mask} and appropriate \impldef{conversions +of \tcode{basic_simd_mask} from/to implementation-specific vector types} types. +\begin{note} +Appropriate types are non-standard vector types which are available in the +implementation. +\end{note} + +\rSec3[simd.mask.ctor]{\tcode{basic_simd_mask} constructors} + +\begin{itemdecl} +constexpr explicit basic_simd_mask(value_type x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes each element with \tcode{x}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr explicit basic_simd_mask(const basic_simd_mask& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{basic_simd_mask::size() == size()} is +\tcode{true}. + +\pnum +\effects +Initializes the $i^\text{th}$ element with \tcode{x[$i$]} for all $i$ in the +range of \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +template constexpr explicit basic_simd_mask(G&& gen); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{gen(integral_constant<\exposid{simd-size-type}, i>())} is +well-formed and its type is \tcode{bool} for all $i$ in the range of +\range{0}{size()}. + +\pnum +\effects +Initializes the $i^\text{th}$ element with +\tcode{gen(integral_constant<\exposid{simd-size-type}, i>())} for all $i$ in +the range of \range{0}{size()}. + +\pnum +\remarks +\tcode{gen} is invoked exactly once for each $i$, in increasing order of $i$. +\end{itemdescr} + +\rSec3[simd.mask.subscr]{\tcode{basic_simd_mask} subscript operator} + +\begin{itemdecl} +constexpr value_type operator[](@\exposid{simd-size-type}@ i) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i >= 0 \&\& i < size()} is \tcode{true}. + +\pnum +\returns +The value of the $i^\text{th}$ element. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\rSec3[simd.mask.unary]{\tcode{basic_simd_mask} unary operators} + +\begin{itemdecl} +constexpr basic_simd_mask operator!() const noexcept; +constexpr basic_simd<@\exposid{integer-from}@, Abi> operator+() const noexcept; +constexpr basic_simd<@\exposid{integer-from}@, Abi> operator-() const noexcept; +constexpr basic_simd<@\exposid{integer-from}@, Abi> operator~() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\returns +A data-parallel object where the $i^\text{th}$ element is initialized to the +results of applying \placeholder{op} to \tcode{operator[]($i$)} for all $i$ in +the range of \range{0}{size()}. +\end{itemdescr} + +\rSec3[simd.mask.conv]{\tcode{basic_simd_mask} conversion operators} + +\begin{itemdecl} +template + constexpr explicit(sizeof(U) != Bytes) operator basic_simd() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{\exposid{simd-size-v} == \exposid{simd-size-v}}. + +\pnum +\returns +A data-parallel object where the $i^\text{th}$ element is initialized to +\tcode{static_cast(operator[]($i$))}. +\end{itemdescr} + +\rSec2[simd.mask.nonmembers]{Non-member operations} + +\rSec3[simd.mask.binary]{\tcode{basic_simd_mask} binary operators} + +\begin{itemdecl} +friend constexpr basic_simd_mask + operator&&(const basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask + operator||(const basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask + operator& (const basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask + operator| (const basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask + operator^ (const basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\returns +A \tcode{basic_simd_mask} object initialized with the results of applying +\placeholder{op} to \tcode{lhs} and \tcode{rhs} as a binary element-wise +operation. +\end{itemdescr} + +\rSec3[simd.mask.cassign]{\tcode{basic_simd_mask} compound assignment} + +\begin{itemdecl} +friend constexpr basic_simd_mask& + operator&=(basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask& + operator|=(basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +friend constexpr basic_simd_mask& + operator^=(basic_simd_mask& lhs, const basic_simd_mask& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\effects +These operators apply \placeholder{op} to \tcode{lhs} and \tcode{rhs} as a +binary element-wise operation. + +\pnum +\returns +\tcode{lhs}. +\end{itemdescr} + +\rSec3[simd.mask.comparison]{\tcode{basic_simd_mask} comparisons} + +\begin{itemdecl} +friend constexpr basic_simd_mask + operator==(const basic_simd_mask&, const basic_simd_mask&) noexcept; +friend constexpr basic_simd_mask + operator!=(const basic_simd_mask&, const basic_simd_mask&) noexcept; +friend constexpr basic_simd_mask + operator>=(const basic_simd_mask&, const basic_simd_mask&) noexcept; +friend constexpr basic_simd_mask + operator<=(const basic_simd_mask&, const basic_simd_mask&) noexcept; +friend constexpr basic_simd_mask + operator>(const basic_simd_mask&, const basic_simd_mask&) noexcept; +friend constexpr basic_simd_mask + operator<(const basic_simd_mask&, const basic_simd_mask&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \placeholder{op} be the operator. + +\pnum +\returns +A \tcode{basic_simd_mask} object initialized with the results of applying +\placeholder{op} to \tcode{lhs} and \tcode{rhs} as a binary element-wise +operation. +\end{itemdescr} + +\rSec3[simd.mask.cond]{\tcode{basic_simd_mask} exposition only conditional operators} + +\begin{itemdecl} +friend constexpr basic_simd_mask @\exposid{simd-select-impl}@( + const basic_simd_mask& mask, const basic_simd_mask& a, const basic_simd_mask& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_simd_mask} object where the $i^\text{th}$ element equals +\tcode{mask[$i$] ? a[$i$] : b[$i$]} for all $i$ in the range of +\range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr basic_simd_mask +@\exposid{simd-select-impl}@(const basic_simd_mask& mask, @\libconcept{same_as}@ auto a, @\libconcept{same_as}@ auto b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_simd_mask} object where the $i^\text{th}$ element equals +\tcode{mask[$i$] ? a : b} for all $i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +template + friend constexpr simd<@\seebelow@, size()> + @\exposid{simd-select-impl}@(const basic_simd_mask& mask, const T0& a, const T1& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + \tcode{same_as} is \tcode{true}, + \item + \tcode{T0} is a vectorizable type, and + \item + \tcode{sizeof(T0) == Bytes}. +\end{itemize} + +\pnum +\returns +A \tcode{simd} object where the $i^\text{th}$ element equals +\tcode{mask[$i$] ? a : b} for all $i$ in the range of \range{0}{size()}. +\end{itemdescr} + +\rSec3[simd.mask.reductions]{\tcode{basic_simd_mask} reductions} + +\begin{itemdecl} +template + constexpr bool all_of(const basic_simd_mask& k) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if all boolean elements in \tcode{k} are \tcode{true}, otherwise +\tcode{false}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr bool any_of(const basic_simd_mask& k) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if at least one boolean element in \tcode{k} is \tcode{true}, +otherwise \tcode{false}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr bool none_of(const basic_simd_mask& k) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!any_of(k)}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr @\exposid{simd-size-type}@ reduce_count(const basic_simd_mask& k) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The number of boolean elements in \tcode{k} that are \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr @\exposid{simd-size-type}@ reduce_min_index(const basic_simd_mask& k); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{any_of(k)} is \tcode{true}. + +\pnum +\returns +The lowest element index $i$ where \tcode{k[$i$]} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr @\exposid{simd-size-type}@ reduce_max_index(const basic_simd_mask& k); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{any_of(k)} is \tcode{true}. + +\pnum +\returns +The greatest element index $i$ where \tcode{k[$i$]} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +constexpr bool all_of(@\libconcept{same_as}@ auto x) noexcept; +constexpr bool any_of(@\libconcept{same_as}@ auto x) noexcept; +constexpr @\exposid{simd-size-type}@ reduce_count(@\libconcept{same_as}@ auto x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x}. +\end{itemdescr} + +\begin{itemdecl} +constexpr bool none_of(@\libconcept{same_as}@ auto x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!x}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{simd-size-type}@ reduce_min_index(@\libconcept{same_as}@ auto x); +constexpr @\exposid{simd-size-type}@ reduce_max_index(@\libconcept{same_as}@ auto x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x} is \tcode{true}. + +\pnum +\returns +\tcode{0}. +\end{itemdescr} + +\rSec1[numerics.c]{C compatibility} + +\rSec2[stdckdint.h.syn]{Header \tcode{} synopsis} + +\indexheader{stdckdint.h}% +\begin{codeblock} +#define @\libmacro{__STDC_VERSION_STDCKDINT_H__}@ 202311L + +template + bool ckd_add(type1* result, type2 a, type3 b); +template + bool ckd_sub(type1* result, type2 a, type3 b); +template + bool ckd_mul(type1* result, type2 a, type3 b); +\end{codeblock} + +\pnum +\xref{\IsoCUndated{}:2024, 7.20} %% TODO: change to \xrefc{7.20} + +\rSec2[numerics.c.ckdint]{Checked integer operations} + +\indexlibraryglobal{ckd_add}% +\indexlibraryglobal{ckd_sub}% +\indexlibraryglobal{ckd_mul}% +\begin{itemdecl} +template + bool ckd_add(type1* result, type2 a, type3 b); +template + bool ckd_sub(type1* result, type2 a, type3 b); +template + bool ckd_mul(type1* result, type2 a, type3 b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +Each of the types \tcode{type1}, \tcode{type2}, and \tcode{type3} is a +cv-unqualified signed or unsigned integer type. + +\pnum +\remarks +Each function template has the same semantics as +the corresponding type-generic macro with the same name +specified in \IsoCUndated{}:2024, 7.20. +\end{itemdescr} diff --git a/source/overloading.tex b/source/overloading.tex index 9e1292a793..5343a015a7 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -464,11 +464,28 @@ argument as in a qualified function call. If the current class is, or is derived from, \tcode{T}, and the keyword \keyword{this}\iref{expr.prim.this} refers to it, -then the implied object argument is \tcode{(*this)}. +\begin{itemize} +\item +if the unqualified function call +appears in a precondition assertion of a constructor +or a postcondition assertion of a destructor +and overload resolution selects a non-static member function, +the call is ill-formed; +\item +otherwise, +the implied object argument is +\tcode{(*\keyword{this})}. +\end{itemize} Otherwise, +\begin{itemize} +\item +if overload resolution selects a non-static member function, +the call is ill-formed; +\item +otherwise, a contrived object of type \tcode{T} -becomes the implied object argument; +becomes the implied object argument. \begin{footnote} An implied object argument is contrived to correspond to the implicit object @@ -482,12 +499,12 @@ reject a function. \end{footnote} -if overload resolution selects a non-static member function, -the call is ill-formed. +\end{itemize} + \begin{example} \begin{codeblock} struct C { - void a(); + bool a(); void b() { a(); // OK, \tcode{(*this).a()} } @@ -524,6 +541,15 @@ void m(this const C& c) { c.k(); // OK } + + C() + pre(a()) // error: implied \keyword{this} in constructor precondition + pre(this->a()) // OK + post(a()); // OK + ~C() + pre(a()) // OK + post(a()) // error: implied \keyword{this} in destructor postcondition + post(this->a()); // OK }; \end{codeblock} \end{example} @@ -676,7 +702,7 @@ \hdstyle{Subclause} & \hdstyle{Expression} & \hdstyle{As member function} & \hdstyle{As non-member function} \\ \capsep \ref{over.unary} & \tcode{@a} & \tcode{(a).\keyword{operator}@ (\,)} & \tcode{\keyword{operator}@(a)} \\ \ref{over.binary} & \tcode{a@b} & \tcode{(a).\keyword{operator}@ (b)} & \tcode{\keyword{operator}@(a, b)} \\ -\ref{over.ass} & \tcode{a=b} & \tcode{(a).\keyword{operator}= (b)} & \\ +\ref{over.assign} & \tcode{a=b} & \tcode{(a).\keyword{operator}= (b)} & \\ \ref{over.sub} & \tcode{a[b]} & \tcode{(a).\keyword{operator}[](b)} & \\ \ref{over.ref} & \tcode{a->} & \tcode{(a).\keyword{operator}->(\,)} & \\ \ref{over.inc} & \tcode{a@} & \tcode{(a).\keyword{operator}@ (0)} & \tcode{\keyword{operator}@(a, 0)} \\ @@ -1006,7 +1032,7 @@ all the constructors of the class of the object being initialized. Otherwise, the candidate functions are all -the converting constructors\iref{class.conv.ctor} of that +the non-explicit constructors\iref{class.conv.ctor} of that class. The argument list is the \grammarterm{expression-list} or \grammarterm{assignment-expression} @@ -1037,7 +1063,7 @@ \begin{itemize} \item -The converting constructors\iref{class.conv.ctor} of +The non-explicit constructors\iref{class.conv.ctor} of \tcode{T} are candidate functions. \item @@ -1118,11 +1144,11 @@ \begin{itemize} \item ``lvalue reference to \cvqual{cv2} \tcode{T2}'' -(when initializing an lvalue reference or an rvalue reference to function) and +(when converting to an lvalue) and \item ``\cvqual{cv2} \tcode{T2}'' -and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' (when initializing an -rvalue reference or an lvalue reference to function) +and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' +(when converting to an rvalue or an lvalue of function type) \end{itemize} for any \tcode{T2}. The permissible types for non-explicit conversion functions are @@ -1173,7 +1199,7 @@ chosen, the initialization is ill-formed. \begin{note} This differs from other situations\iref{over.match.ctor,over.match.copy}, -where only converting constructors are considered for copy-initialization. +where only non-explicit constructors are considered for copy-initialization. This restriction only applies if this initialization is part of the final result of overload resolution. @@ -1734,10 +1760,10 @@ (see~\ref{dcl.init}, \ref{over.match.conv}, and~\ref{over.match.ref}) and the standard conversion sequence -from the return type of $\tcode{F}_1$ to the destination type +from the result of $\tcode{F}_1$ to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence -from the return type of $\tcode{F}_2$ to the destination type +from the result of $\tcode{F}_2$ to the destination type \begin{example} \begin{codeblock} struct A { @@ -1755,8 +1781,8 @@ \item the context is an initialization by conversion function for direct reference binding\iref{over.match.ref} of a reference to function type, the -return type of \tcode{F1} is the same kind of reference (lvalue or rvalue) -as the reference being initialized, and the return type of \tcode{F2} is not +return type of $\tcode{F}_1$ is the same kind of reference (lvalue or rvalue) +as the reference being initialized, and the return type of $\tcode{F}_2$ is not \begin{example} \begin{codeblock} template struct A { @@ -1772,43 +1798,31 @@ or, if not that, \item -\tcode{F1} +$\tcode{F}_1$ is not a function template specialization and -\tcode{F2} +$\tcode{F}_2$ is a function template specialization, or, if not that, \item -\tcode{F1} +$\tcode{F}_1$ and -\tcode{F2} +$\tcode{F}_2$ are function template specializations, and the function template for -\tcode{F1} +$\tcode{F}_1$ is more specialized than the template for -\tcode{F2} +$\tcode{F}_2$ according to the partial ordering rules described in~\ref{temp.func.order}, or, if not that, \item -\tcode{F1} and \tcode{F2} are non-template functions and -\begin{itemize} -\item -they have the same non-object-parameter-type-lists\iref{dcl.fct}, and -\item -if they are member functions, both are direct members of the same class, and -\item -if both are non-static member functions, -they have the same types for their object parameters, and -\item -\tcode{F1} is more constrained than \tcode{F2} -according to the partial ordering of constraints described in -\ref{temp.constr.order}, -\end{itemize} -or if not that, +$\tcode{F}_1$ and $\tcode{F}_2$ are non-template functions and +$\tcode{F}_1$ is more partial-ordering-constrained than +$\tcode{F}_2$\iref{temp.constr.order} \begin{example} \begin{codeblock} template @@ -1823,12 +1837,13 @@ } \end{codeblock} \end{example} +or, if not that, \item -\tcode{F1} is a constructor for a class \tcode{D}, -\tcode{F2} is a constructor for a base class \tcode{B} of \tcode{D}, and +$\tcode{F}_1$ is a constructor for a class \tcode{D}, +$\tcode{F}_2$ is a constructor for a base class \tcode{B} of \tcode{D}, and for all arguments -the corresponding parameters of \tcode{F1} and \tcode{F2} have the same type +the corresponding parameters of $\tcode{F}_1$ and $\tcode{F}_2$ have the same type \begin{example} \begin{codeblock} struct A { @@ -1848,8 +1863,8 @@ or, if not that, \item -\tcode{F2} is a rewritten candidate\iref{over.match.oper} and -\tcode{F1} is not +$\tcode{F}_2$ is a rewritten candidate\iref{over.match.oper} and +$\tcode{F}_1$ is not \begin{example} \begin{codeblock} struct S { @@ -1862,10 +1877,10 @@ or, if not that, \item -\tcode{F1} and \tcode{F2} are rewritten candidates, and -\tcode{F2} is a synthesized candidate +$\tcode{F}_1$ and $\tcode{F}_2$ are rewritten candidates, and +$\tcode{F}_2$ is a synthesized candidate with reversed order of parameters -and \tcode{F1} is not +and $\tcode{F}_1$ is not \begin{example} \begin{codeblock} struct S { @@ -1875,32 +1890,32 @@ bool b = 1 < S(); // calls \#2 \end{codeblock} \end{example} -or, if not that +or, if not that, \item -\tcode{F1} and \tcode{F2} are generated +$\tcode{F}_1$ and $\tcode{F}_2$ are generated from class template argument deduction\iref{over.match.class.deduct} for a class \tcode{D}, and -\tcode{F2} is generated +$\tcode{F}_2$ is generated from inheriting constructors from a base class of \tcode{D} -while \tcode{F1} is not, and +while $\tcode{F}_1$ is not, and for each explicit function argument, -the corresponding parameters of \tcode{F1} and \tcode{F2} +the corresponding parameters of $\tcode{F}_1$ and $\tcode{F}_2$ are either both ellipses or have the same type, or, if not that, \item -\tcode{F1} is generated from a +$\tcode{F}_1$ is generated from a \grammarterm{deduction-guide}\iref{over.match.class.deduct} -and \tcode{F2} is not, or, if not that, +and $\tcode{F}_2$ is not, or, if not that, \item -\tcode{F1} is the copy deduction candidate\iref{over.match.class.deduct} -and \tcode{F2} is not, or, if not that, +$\tcode{F}_1$ is the copy deduction candidate\iref{over.match.class.deduct} +and $\tcode{F}_2$ is not, or, if not that, \item -\tcode{F1} is generated from a non-template constructor -and \tcode{F2} is generated from a constructor template. +$\tcode{F}_1$ is generated from a non-template constructor +and $\tcode{F}_2$ is generated from a constructor template. \begin{example} \begin{codeblock} template struct A { @@ -2296,7 +2311,7 @@ \pnum If the user-defined conversion is specified by a specialization of a conversion function template, -the second standard conversion sequence shall have exact match rank. +the second standard conversion sequence shall have Exact Match rank. \pnum A conversion of an expression of class type @@ -2318,7 +2333,7 @@ \rSec4[over.ics.ref]{Reference binding} \pnum -When a parameter of type ``reference to \cv \tcode{T}'' +When a parameter of type ``reference to \cv~\tcode{T}'' binds directly\iref{dcl.init.ref} to an argument expression: \begin{itemize} \item @@ -2329,16 +2344,16 @@ \item Otherwise, -if \tcode{T} is a function type, or if the type of the argument is possibly cv-qualified \tcode{T}, or if \tcode{T} is an array type of unknown bound with element type \tcode{U} and the argument has an array type of known bound whose element type is possibly cv-qualified \tcode{U}, the implicit conversion sequence is the identity conversion. -\begin{note} -When \tcode{T} is a function type, -the type of the argument can differ only by the presence of \keyword{noexcept}. -\end{note} + +\item +Otherwise, +if \tcode{T} is a function type, +the implicit conversion sequence is a function pointer conversion. \item Otherwise, the implicit conversion sequence is a qualification conversion. @@ -2351,6 +2366,11 @@ int f(A&); int f(B&); int i = f(b); // calls \tcode{f(B\&)}, an exact match, rather than \tcode{f(A\&)}, a conversion + +void g() noexcept; +int h(void (&)() noexcept); // \#1 +int h(void (&)()); // \#2 +int j = h(g); // calls \#1, an exact match, rather than \#2, a function pointer conversion \end{codeblock} \end{example} If the parameter binds directly to the result of @@ -2792,7 +2812,7 @@ (where a standard conversion sequence that is a reference binding is considered to yield the cv-unqualified referenced type), where \tcode{T1} and \tcode{T2} are not the same type, and -\tcode{const T2} is reference-compatible with \tcode{T1}\iref{dcl.init.ref}. +\tcode{const T2} is reference-compatible with \tcode{T1}\iref{dcl.init.ref} \begin{example} \begin{codeblock} int f(const volatile int *); @@ -2806,6 +2826,7 @@ \end{codeblock} \end{example} or, if not that, + \item \tcode{S1} and @@ -2813,7 +2834,7 @@ bind ``reference to \tcode{T1}'' and ``reference to \tcode{T2}'', respectively\iref{dcl.init.ref}, where \tcode{T1} and \tcode{T2} are not the same type, and -\tcode{T2} is reference-compatible with \tcode{T1}. +\tcode{T2} is reference-compatible with \tcode{T1} \begin{example} \begin{codeblock} int f(const int &); @@ -2834,18 +2855,40 @@ b.f(); // calls \tcode{X::f()} } -int h1(int (&)[]); -int h1(int (&)[1]); -int h2(void (&)()); -int h2(void (&)() noexcept); +int h(int (&)[]); +int h(int (&)[1]); void g2() { int a[1]; - h1(a); // calls \tcode{h1(int (\&)[1])} - extern void f2() noexcept; - h2(f2); // calls \tcode{h2(void (\&)() noexcept)} + h(a); // calls \tcode{h(int (\&)[1])} } \end{codeblock} \end{example} +or, if not that, + +\item +\tcode{S1} and \tcode{S2} +bind the same reference type ``reference to \tcode{T}'' and +have source types \tcode{V1} and \tcode{V2}, respectively, +where the standard conversion sequence from \tcode{V1*} to \tcode{T*} +is better than the standard conversion sequence from \tcode{V2*} to \tcode{T*}. +\begin{example} +\begin{codeblock} +struct Z {}; + +struct A { + operator Z&(); + operator const Z&(); // \#1 +}; + +struct B { + operator Z(); + operator const Z&&(); // \#2 +}; + +const Z& r1 = A(); // OK, uses \#1 +const Z&& r2 = B(); // OK, uses \#2 +\end{codeblock} +\end{example} \end{itemize} \item @@ -3076,7 +3119,7 @@ \item an object or reference being initialized\iref{dcl.init,dcl.init.ref,dcl.init.list}, \item -the left side of an assignment\iref{expr.ass}, +the left side of an assignment\iref{expr.assign}, \item a parameter of a function\iref{expr.call}, \item @@ -3086,9 +3129,11 @@ \item an explicit type conversion\iref{expr.type.conv,expr.static.cast,expr.cast}, or \item -a non-type -\grammarterm{template-parameter}\iref{temp.arg.nontype}. +a constant template parameter\iref{temp.arg.nontype}. \end{itemize} +If the target type contains a placeholder type, +placeholder type deduction is performed\iref{dcl.type.auto.deduct}, and +the remainder of this subclause uses the target type so deduced. The \grammarterm{id-expression} can be preceded by the \tcode{\&} operator. \begin{note} Any redundant set of parentheses surrounding the function name is @@ -3141,10 +3186,8 @@ \tcode{F0} is eliminated if the set contains a second non-template function that -is more constrained than -\tcode{F0} -according to -the partial ordering rules of \ref{temp.constr.order}. +is more partial-ordering-constrained than +\tcode{F0}\iref{temp.constr.order}. Any given function template specialization \tcode{F1} @@ -3180,8 +3223,9 @@ with type \tcode{int(...)} has been declared, and not because of any ambiguity. -For another example, +\end{example} +\begin{example} \begin{codeblock} struct X { int f(int); @@ -3198,6 +3242,21 @@ \end{codeblock} \end{example} +\begin{example} +\begin{codeblock} +template struct X { + void f(short) requires B; + void f(long); + template void g(short) requires B; + template void g(long); +}; +void test() { + &X::f; // error: ambiguous; constraints are not considered + &X::g; // error: ambiguous; constraints are not considered +} +\end{codeblock} +\end{example} + \pnum \begin{note} If \tcode{f} and \tcode{g} are both overload sets, @@ -3248,13 +3307,13 @@ \begin{bnf} %% Ed. note: character protrusion would misalign various operators. -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{operator} \textnormal{one of}\br - \terminal{new delete new[] delete[] co_await (\rlap{\,)} [\rlap{\,]} -> ->*}\br - \terminal{\~ ! + - * / \% \caret{} \&}\br - \terminal{| = += -= *= /= \%= \caret{}= \&=}\br - \terminal{|= == != < > <= >= <=> \&\&}\br - \terminal{|| << >> <<= >>= ++ -- ,}\br + \terminal{new \ \ \ \ \ delete \ \ new[] \ \ \ delete[] co_await (\rlap{\,)} \ \ \ \ \ \ \ [\rlap{\,]} \ \ \ \ \ \ \ -> \ \ \ \ \ \ ->*}\br + \terminal{\~ \ \ \ \ \ \ \ ! \ \ \ \ \ \ \ + \ \ \ \ \ \ \ - \ \ \ \ \ \ \ * \ \ \ \ \ \ \ / \ \ \ \ \ \ \ \% \ \ \ \ \ \ \ \caret{} \ \ \ \ \ \ \ \&}\br + \terminal{| \ \ \ \ \ \ \ = \ \ \ \ \ \ \ += \ \ \ \ \ \ -= \ \ \ \ \ \ *= \ \ \ \ \ \ /= \ \ \ \ \ \ \%= \ \ \ \ \ \ \caret{}= \ \ \ \ \ \ \&=}\br + \terminal{|= \ \ \ \ \ \ == \ \ \ \ \ \ != \ \ \ \ \ \ < \ \ \ \ \ \ \ > \ \ \ \ \ \ \ <= \ \ \ \ \ \ >= \ \ \ \ \ \ <=> \ \ \ \ \ \&\&}\br + \terminal{|| \ \ \ \ \ \ << \ \ \ \ \ \ >> \ \ \ \ \ \ <<= \ \ \ \ \ >>= \ \ \ \ \ ++ \ \ \ \ \ \ -- \ \ \ \ \ \ ,}\br \end{bnf} \begin{note} The operators @@ -3272,8 +3331,8 @@ \pnum Both the unary and binary forms of -\begin{ncsimplebnf}\obeyspaces -\terminal{+ - * \&} +\begin{ncsimplebnf} +\terminal{+ \ \ \ \ \ - \ \ \ \ \ * \ \ \ \ \ \&} \end{ncsimplebnf} can be overloaded. @@ -3281,8 +3340,8 @@ \begin{note} \indextext{restriction!operator overloading}% The following operators cannot be overloaded: -\begin{ncsimplebnf}\obeyspaces -\terminal{. .* :: ?:} +\begin{ncsimplebnf} +\terminal{. \ \ \ \ \ .* \ \ \ \ :: \ \ \ \ ?:} \end{ncsimplebnf} nor can the preprocessing symbols \tcode{\#}\iref{cpp.stringize} @@ -3324,15 +3383,10 @@ \pnum \indextext{restriction!overloading}% An operator function -shall either -\begin{itemize} -\item -be a member function or -\item -be a non-member function that -has at least one non-object parameter whose type is a class, a reference to a class, an +shall have at least one +function parameter or implicit object parameter whose type is +a class, a reference to a class, an enumeration, or a reference to an enumeration. -\end{itemize} It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of @@ -3353,14 +3407,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} @@ -3374,7 +3428,7 @@ described in the rest of \ref{over.oper}. \pnum -Operators not mentioned explicitly in subclauses~\ref{over.ass} through~\ref{over.inc} +Operators not mentioned explicitly in subclauses~\ref{over.assign} through~\ref{over.inc} act as ordinary unary and binary operators obeying the rules of~\ref{over.unary} or~\ref{over.binary}.% \indextext{overloading!resolution!best viable function|)}% @@ -3455,7 +3509,7 @@ a relational operator function, or a three-way comparison operator function. -\rSec3[over.ass]{Simple assignment} +\rSec3[over.assign]{Simple assignment} \indextext{assignment operator!overloaded}% \indextext{overloading!assignment operator} @@ -4066,12 +4120,13 @@ A \defnx{numeric literal operator template}{literal!operator!template numeric} is a literal operator template whose \grammarterm{template-parameter-list} has a single \grammarterm{template-parameter} -that is a non-type template parameter pack\iref{temp.variadic} +that is a constant template parameter pack\iref{temp.variadic} with element type \tcode{char}. A \defnx{string literal operator template}{literal!operator!template string} is a literal operator template whose \grammarterm{template-parameter-list} comprises -a single non-type \grammarterm{template-parameter} of class type. +a single \grammarterm{parameter-declaration} that declares a +constant template parameter of class type. The declaration of a literal operator template shall have an empty \grammarterm{parameter-declaration-clause} and shall declare either a numeric literal operator template diff --git a/source/preface.tex b/source/preface.tex index b77caca873..6e0b3fa036 100644 --- a/source/preface.tex +++ b/source/preface.tex @@ -9,7 +9,7 @@ \chapter{Introduction} Clauses and subclauses in this document are annotated with a so-called stable name, presented in square brackets next to the (sub)clause heading -(such as ``[lex.token]'' for subclause \ref{lex.token}, ``Tokens''). +(such as ``[lex.token]'' for \ref{lex.token}, ``Tokens''). Stable names aid in the discussion and evolution of this document by serving as stable references to subclauses across editions that are unaffected by changes of subclause numbering. diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 913fcc20fb..ee7959abeb 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -45,17 +45,18 @@ \terminal{\#} conditionally-supported-directive \end{bnf} -\begin{bnf}\obeyspaces +\begin{bnf} \nontermdef{control-line}\br \terminal{\# include} pp-tokens new-line\br pp-import\br + \terminal{\# embed \ } pp-tokens new-line\br \terminal{\# define } identifier replacement-list new-line\br \terminal{\# define } identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br \terminal{\# define } identifier lparen \terminal{... )} replacement-list new-line\br \terminal{\# define } identifier lparen identifier-list \terminal{, ... )} replacement-list new-line\br - \terminal{\# undef } identifier new-line\br - \terminal{\# line } pp-tokens new-line\br - \terminal{\# error } \opt{pp-tokens} new-line\br + \terminal{\# undef \ } identifier new-line\br + \terminal{\# line \ \ } pp-tokens new-line\br + \terminal{\# error \ } \opt{pp-tokens} new-line\br \terminal{\# warning} \opt{pp-tokens} new-line\br \terminal{\# pragma } \opt{pp-tokens} new-line\br \terminal{\# }new-line @@ -66,34 +67,33 @@ if-group \opt{elif-groups} \opt{else-group} endif-line \end{bnf} -\begin{bnf}\obeyspaces +\begin{bnf} \nontermdef{if-group}\br - \terminal{\# if } constant-expression new-line \opt{group}\br - \terminal{\# ifdef } identifier new-line \opt{group}\br + \terminal{\# if \ \ \ \ } constant-expression new-line \opt{group}\br + \terminal{\# ifdef \ } identifier new-line \opt{group}\br \terminal{\# ifndef } identifier new-line \opt{group} \end{bnf} \begin{bnf} \nontermdef{elif-groups}\br - elif-group\br - elif-groups elif-group + elif-group \opt{elif-groups} \end{bnf} -\begin{bnf}\obeyspaces +\begin{bnf} \nontermdef{elif-group}\br - \terminal{\# elif } constant-expression new-line \opt{group}\br + \terminal{\# elif \ \ \ } constant-expression new-line \opt{group}\br \terminal{\# elifdef } identifier new-line \opt{group}\br \terminal{\# elifndef} identifier new-line \opt{group} \end{bnf} -\begin{bnf}\obeyspaces +\begin{bnf} \nontermdef{else-group}\br - \terminal{\# else } new-line \opt{group} + \terminal{\# else \ \ } new-line \opt{group} \end{bnf} -\begin{bnf}\obeyspaces +\begin{bnf} \nontermdef{endif-line}\br - \terminal{\# endif } new-line + \terminal{\# endif \ } new-line \end{bnf} \begin{bnf} @@ -124,8 +124,48 @@ \begin{bnf} \nontermdef{pp-tokens}\br - preprocessing-token\br - pp-tokens preprocessing-token + preprocessing-token \opt{pp-tokens} +\end{bnf} + +\begin{bnf} +\nontermdef{embed-parameter-seq}\br + embed-parameter \opt{embed-parameter-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{embed-parameter}\br + embed-standard-parameter\br + embed-prefixed-parameter +\end{bnf} + +\begin{bnf} +\nontermdef{embed-standard-parameter}\br + \terminal{limit} \terminal{(} pp-balanced-token-seq \terminal{)}\br + \terminal{prefix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br + \terminal{suffix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br + \terminal{if_empty} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{embed-prefixed-parameter}\br + identifier :: identifier\br + identifier :: identifier \terminal{(} \opt{pp-balanced-token-seq} \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-balanced-token-seq}\br + pp-balanced-token \opt{pp-balanced-token-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{pp-balanced-token}\br + \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br + \terminal{[} \opt{pp-balanced-token-seq} \terminal{]}\br + \terminal{\{} \opt{pp-balanced-token-seq} \terminal{\}}\br + \textnormal{any} pp-token \textnormal{except:}\br + \bnfindent\textnormal{parenthesis (\unicode{0028}{left parenthesis} and \unicode{0029}{right parenthesis}),}\br + \bnfindent\textnormal{bracket (\unicode{005b}{left square bracket} and \unicode{005d}{right square bracket}), or}\br + \bnfindent\textnormal{brace (\unicode{007b}{left curly bracket} and \unicode{007d}{right curly bracket}).} \end{bnf} \begin{bnf} @@ -137,7 +177,7 @@ A \defn{preprocessing directive} consists of a sequence of preprocessing tokens that satisfies the following constraints: At the start of translation phase 4, -the first token in the sequence, +the first preprocessing token in the sequence, referred to as a \defnadj{directive-introducing}{token}, begins with the first character in the source file (optionally after whitespace containing no new-line characters) or @@ -150,7 +190,7 @@ \item an \keyword{import} preprocessing token -immediately followed on the same logical line by a +immediately followed on the same logical source line by a \grammarterm{header-name}, \tcode{<}, \grammarterm{identifier}, @@ -160,7 +200,7 @@ \item a \keyword{module} preprocessing token -immediately followed on the same logical line by an +immediately followed on the same logical source line by an \grammarterm{identifier}, \tcode{:}, or \tcode{;} @@ -168,11 +208,11 @@ \item an \keyword{export} preprocessing token -immediately followed on the same logical line by +immediately followed on the same logical source line by one of the two preceding forms. \end{itemize} -The last token in the sequence is the first token within the sequence that +The last preprocessing token in the sequence is the first preprocessing token within the sequence that is immediately followed by whitespace containing a new-line character. \begin{footnote} Thus, @@ -216,6 +256,16 @@ \pnum A sequence of preprocessing tokens is only a \grammarterm{text-line} if it does not begin with a directive-introducing token. +\begin{example} +\begin{codeblock} +using module = int; +module i; // not a \grammarterm{text-line} and not a \grammarterm{control-line} +int foo() { + return i; +} +\end{codeblock} +The example is not a valid \grammarterm{preprocessing-file}. +\end{example} A sequence of preprocessing tokens is only a \grammarterm{conditionally-supported-directive} if it does not begin with any of the directive names appearing after a \tcode{\#} in the syntax. @@ -224,6 +274,10 @@ \impldef{additional supported forms of preprocessing directive} semantics. +\pnum +Any \grammarterm{embed-prefixed-parameter} is conditionally-supported, +with \impldef{supported forms of \#embed prefix parameters} semantics. + \pnum At the start of phase 4 of translation, the \grammarterm{group} of a \grammarterm{pp-global-module-fragment} shall @@ -290,8 +344,7 @@ \begin{bnf} \nontermdef{h-pp-tokens}\br - h-preprocessing-token\br - h-pp-tokens h-preprocessing-token + h-preprocessing-token \opt{h-pp-tokens} \end{bnf} \begin{bnf} @@ -307,6 +360,12 @@ \terminal{\xname{has_include}} \terminal{(} header-name-tokens \terminal{)} \end{bnf} +\indextext{\idxxname{has_embed}}% +\begin{bnf} +\nontermdef{has-embed-expression}\br + \terminal{\xname{has_embed}} \terminal{(} pp-balanced-token-seq \terminal{)} +\end{bnf} + \indextext{\idxxname{has_cpp_attribute}}% \begin{bnf} \nontermdef{has-attribute-expression}\br @@ -325,9 +384,12 @@ all identifiers either are or are not macro names --- there simply are no keywords, enumeration constants, etc. \end{footnote} -and it may contain zero or more \grammarterm{defined-macro-expression}{s} and/or -\grammarterm{has-include-expression}{s} and/or -\grammarterm{has-attribute-expression}{s} as unary operator expressions. +and it may contain zero or more +\grammarterm{defined-macro-expression}{s}, +\grammarterm{has-include-expression}{s}, +\grammarterm{has-attribute-expression}{s}, +and/or \grammarterm{has-embed-expression}{s} +as unary operator expressions. \pnum A \grammarterm{defined-macro-expression} evaluates to \tcode{1} @@ -361,6 +423,31 @@ to \tcode{1} if the search for the source file succeeds, and to \tcode{0} if the search fails. +\pnum +The parenthesized \grammarterm{pp-balanced-token-seq} in each contained +\grammarterm{has-embed-expression} is processed as if that +\grammarterm{pp-balanced-token-seq} were the \grammarterm{pp-tokens} in the +third form of a \tcode{\#embed} directive\iref{cpp.embed}. +If such a directive would not satisfy the syntactic requirements of a +\tcode{\#embed} directive, the program is ill-formed. +The \grammarterm{has-embed-expression} evaluates to: +\begin{itemize} +\item +\mname{STDC_EMBED_FOUND} if the search for the resource succeeds, +all the given \grammarterm{embed-parameter}s in the \grammarterm{embed-parameter-seq} +are supported, and the resource is not empty. +\item +Otherwise, \mname{STDC_EMBED_EMPTY} if the search for the resource succeeds, +all the given \grammarterm{embed-parameter}s in the \grammarterm{embed-parameter-seq} +are supported, and the resource is empty. +\item +Otherwise, \mname{STDC_EMBED_NOT_FOUND}. +\end{itemize} +\begin{note} +An unrecognized \grammarterm{embed-parameter} in an \grammarterm{has-embed-expression} +is not ill-formed and is instead treated as not supported. +\end{note} + \pnum Each \grammarterm{has-attribute-expression} is replaced by a non-zero \grammarterm{pp-number} @@ -393,7 +480,6 @@ \topline \lhdr{Attribute} & \rhdr{Value} \\ \rowsep \tcode{assume} & \tcode{202207L} \\ -\tcode{carries_dependency} & \tcode{200809L} \\ \tcode{deprecated} & \tcode{201309L} \\ \tcode{fallthrough} & \tcode{201603L} \\ \tcode{likely} & \tcode{201803L} \\ @@ -409,9 +495,9 @@ \tcode{\#ifdef}, \tcode{\#ifndef}, \tcode{\#elifdef}, and \tcode{\#elifndef} directives, and the \tcode{defined} conditional inclusion operator, -shall treat \xname{has_include} and \xname{has_cpp_attribute} +shall treat \xname{has_include}, \xname{has_embed}, and \xname{has_cpp_attribute} as if they were the names of defined macros. -The identifiers \xname{has_include} and \xname{has_cpp_attribute} +The identifiers \xname{has_include}, \xname{has_embed}, and \xname{has_cpp_attribute} shall not appear in any context not mentioned in this subclause. \pnum @@ -422,11 +508,11 @@ \pnum Preprocessing directives of the forms -\begin{ncsimplebnf}\obeyspaces +\begin{ncsimplebnf} \indextext{\idxcode{\#if}}% -\terminal{\# if } constant-expression new-line \opt{group}\br +\terminal{\# if \ \ \ \ } constant-expression new-line \opt{group}\br \indextext{\idxcode{\#elif}}% -\terminal{\# elif } constant-expression new-line \opt{group} +\terminal{\# elif \ \ } constant-expression new-line \opt{group} \end{ncsimplebnf} check whether the controlling constant expression evaluates to nonzero. @@ -439,7 +525,7 @@ \tcode{defined} unary operator), just as in normal text. -If the token +If the preprocessing token \tcode{defined} is generated as a result of this replacement process or use of the @@ -452,7 +538,8 @@ After all replacements due to macro expansion and evaluations of \grammarterm{defined-macro-expression}s, -\grammarterm{has-include-expression}s, and +\grammarterm{has-include-expression}s, +\grammarterm{has-embed-expression}s, and \grammarterm{has-attribute-expression}s have been performed, all remaining identifiers and keywords, @@ -498,10 +585,10 @@ \pnum Preprocessing directives of the forms -\begin{ncsimplebnf}\obeyspaces -\terminal{\# ifdef } identifier new-line \opt{group}\br +\begin{ncsimplebnf} +\terminal{\# ifdef \ \ } identifier new-line \opt{group}\br \indextext{\idxcode{\#ifdef}}% -\terminal{\# ifndef } identifier new-line \opt{group}\br +\terminal{\# ifndef \ } identifier new-line \opt{group}\br \indextext{\idxcode{\#ifndef}}% \terminal{\# elifdef } identifier new-line \opt{group}\br \indextext{\idxcode{\#elifdef}}% @@ -661,13 +748,13 @@ If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined. -\begin{footnote} -Note that adjacent \grammarterm{string-literal}s are not concatenated into +\begin{note} +Adjacent \grammarterm{string-literal}s are not concatenated into a single \grammarterm{string-literal} (see the translation phases in~\ref{lex.phases}); thus, an expansion that results in two \grammarterm{string-literal}s is an invalid directive. -\end{footnote} +\end{note} The method by which a sequence of preprocessing tokens between a \tcode{<} and a @@ -745,6 +832,356 @@ \end{codeblock} \end{example} +\rSec1[cpp.embed]{Resource inclusion} +\indextext{preprocessing directive!embed a resource} +\indextext{\idxcode{\#embed}}% + +\rSec2[cpp.embed.gen]{General} + +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# embed <} h-char-sequence \terminal{>} \opt{pp-tokens} new-line +\end{ncsimplebnf} +searches a sequence of +\impldef{sequence of places searched for an embedded resource} +places for a resource identified uniquely by the specified sequence between +the \tcode{<} and \tcode{>} delimiters. +How the places are specified or the resource identified is +\impldef{search locations for embedded resources specified with \tcode{<>}}. + +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# embed "} q-char-sequence \terminal{"} \opt{pp-tokens} new-line +\end{ncsimplebnf} +searches for a resource identified by the specified sequence between the +\tcode{"} delimiters. +The named resource is searched for in an +\impldef{manner of search for named resource} +manner. +If this search is not supported, or if the search fails, the directive is +reprocessed as if it read +\begin{ncsimplebnf} +\terminal{\# embed <} h-char-sequence \terminal{>} \opt{pp-tokens} new-line +\end{ncsimplebnf} +with the identical contained sequence (including \tcode{>} characters, if any) +from the original directive. + +\pnum +\recommended A mechanism similar to, but distinct from, the +\impldef{sequence of places searched for a header} +search paths used for \tcode{\#include} \iref{cpp.include} +is encouraged. + +\pnum +Either form of the \tcode{\#embed} directive processes the +\grammarterm{pp-tokens}, if present, just as in normal text. +The \grammarterm{pp-tokens} shall then have the form +\grammarterm{embed-parameter-seq}. + +\pnum +A resource is a source of data accessible from the translation environment. +A resource has an \defn{implementation-resource-width}, which is the +\impldef{size in bits of a resource} +size in bits of the resource. +If the implementation-resource-width is not an integral multiple of +\libmacro{CHAR_BIT}, the program is ill-formed. +Let \defn{implementation-resource-count} be +implementation-resource-width divided by \libmacro{CHAR_BIT}. +Every resource also has a \defn{resource-count}, which is + +\begin{itemize} +\item + the value as computed from the optionally-provided \tcode{limit} + \grammarterm{embed-parameter}\iref{cpp.embed.param.limit}, if present; +\item + otherwise, the implementation-resource-count. +\end{itemize} + +A resource is empty if the resource-count is zero. + +\pnum +\begin{example} +\begin{codeblock} +// ill-formed if the implementation-resource-width is 6 bits +#embed "6_bits.bin" +\end{codeblock} +\end{example} + +\pnum +The \tcode{\#embed} directive is replaced by a comma-delimited list of integer +literals of type \tcode{int}, unless otherwise modified by embed +parameters\iref{cpp.embed.param}. + +\pnum +The integer literals in the comma-delimited list correspond to +resource-count consecutive calls to \tcode{std::fgetc} \iref{cstdio.syn} +from the resource, as a binary file. +If any call to \tcode{std::fgetc} returns \tcode{EOF}, the program is +ill-formed. + +\pnum +\recommended The value of each integer literal should closely represent +the bit stream of the resource unmodified. +This can require an implementation to consider potential differences between +translation and execution environments, as well as any other applicable +sources of mismatch. + +\begin{example} +\begin{codeblock} +#include +#include +#include +#include +#include + +int main() { + // If the file is the same as the resource in the translation environment, no assert in this program should fail. + constexpr unsigned char d[] = { +#embed + }; + const std::vector vec_d = { +#embed + }; + + constexpr std::size_t expected_size = sizeof(d); + + // same file in execution environment as was embedded + std::ifstream f_source("data.dat", std::ios::binary | std::ios::in); + unsigned char runtime_d[expected_size]; + char* ifstream_ptr = reinterpret_cast(runtime_d); + assert(!f_source.read(ifstream_ptr, expected_size)); + std::size_t ifstream_size = f_source.gcount(); + assert (ifstream_size == expected_size); + int is_same = std::memcmp(&d[0], ifstream_ptr, ifstream_size); + assert(is_same == 0); + int is_same_vec = std::memcmp(vec_d.data(), ifstream_ptr, ifstream_size); + assert(is_same_vec == 0); +} +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +int i = { +#embed "i.dat" +}; // well-formed if \tcode{i.dat} produces a single value +int i2 = +#embed "i.dat" +; // also well-formed if \tcode{i.dat} produces a single value +struct s { + double a, b, c; + struct { double e, f, g; } x; + double h, i, j; +}; +s x = { +// well-formed if the directive produces nine or fewer values +#embed "s.dat" +}; +\end{codeblock} +\end{example} + +\pnum +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# embed} pp-tokens new-line +\end{ncsimplebnf} +(that does not match one of the two previous forms) is permitted. +The preprocessing tokens after \tcode{embed} in the directive are processed +just as in normal text (i.e., each identifier currently defined as a macro +name is replaced by its replacement list of preprocessing tokens). +The directive resulting after all replacements of the third form shall match +one of the two previous forms. +\begin{note} +Adjacent \grammarterm{string-literal}{s} are not concatenated into a single +\grammarterm{string-literal} (see the translation phases in \iref{lex.phases}); +thus, an expansion that results in two \grammarterm{string-literal}{s} is an +invalid directive. +\end{note} + +Any further processing as in normal text described for the two previous +forms is not performed. +\begin{note} +That is, processing as in normal text happens once and only once for the entire +directive. +\end{note} + +\begin{example} +If the directive matches the third form, the whole directive is replaced. +If the directive matches the first two forms, everything after the name is +replaced. + +\begin{codeblock} +#define prefix(ARG) suffix(ARG) +#define THE_ADDITION "teehee" +#define THE_RESOURCE ":3c" +#embed ":3c" prefix(THE_ADDITION) +#embed THE_RESOURCE prefix(THE_ADDITION) +\end{codeblock} + +is equivalent to: + +\begin{codeblock} +#embed ":3c" suffix("teehee") +#embed ":3c" suffix("teehee") +\end{codeblock} +\end{example} + +\pnum +The method by which a sequence of preprocessing tokens between a \tcode{<} and +a \tcode{>} preprocessing token pair or a pair of \tcode{"} characters is +combined into a single resource name preprocessing token is +\impldef{search locations for \tcode{""""} resource}. + +\rSec2[cpp.embed.param]{Embed parameters} +\rSec3[cpp.embed.param.limit]{limit parameter} +\pnum +An \grammarterm{embed-parameter} of the form +\tcode{limit (} \grammarterm{pp-balanced-token-seq} \tcode{)} +specifies the +maximum possible number of elements in the comma-delimited list. +It shall appear at most once in the \grammarterm{embed-parameter-seq}. +The token \tcode{defined} shall not appear in the +\grammarterm{constant-expression}. + +\pnum +The \grammarterm{pp-balanced-token-seq} is evaluated as a +\grammarterm{constant-expression} using the rules as described in conditional +inclusion\iref{cpp.cond}, but without being processed as in normal text an +additional time. + +\begin{example} +\begin{codeblock} +#undef DATA_LIMIT +#if __has_embed( limit(DATA_LIMIT)) +#endif +\end{codeblock} + +is equivalent to: + +\begin{codeblock} +#if __has_embed( limit(0)) +#endif +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +#embed limit(__has_include("a.h")) + +#if __has_embed( limit(__has_include("a.h"))) +// ill-formed: \tcode{__has_include}\iref{cpp.cond} cannot appear here +#endif +\end{codeblock} +\end{example} + +\pnum +The \grammarterm{constant-expression} shall be an integral constant expression +whose value is greater than or equal to zero. +The resource-count\iref{cpp.embed.gen} becomes +implementation-resource-count, if the value of the +\grammarterm{constant-expression} is greater than +implementation-resource-count; otherwise, the value of the +\grammarterm{constant-expression}. +\begin{example} +\begin{codeblock} +constexpr unsigned char sound_signature[] = { + // a hypothetical resource capable of expanding to four or more elements +#embed limit(2+2) +}; + +static_assert(sizeof(sound_signature) == 4); // OK +\end{codeblock} +\end{example} + +\rSec3[cpp.embed.param.prefix]{prefix parameter} +\pnum +An \grammarterm{embed-parameter} of the form +\begin{ncsimplebnf} +\terminal{prefix (} \opt{pp-balanced-token-seq} \terminal{)} +\end{ncsimplebnf} +shall appear at most once in the \grammarterm{embed-parameter-seq}. + +\pnum +If the resource is empty, this \grammarterm{embed-parameter} is ignored. +Otherwise, the \grammarterm{pp-balanced-token-seq} is placed immediately +before the comma-delimited list of integral literals. + +\rSec3[cpp.embed.param.suffix]{suffix parameter} +\pnum +An \grammarterm{embed-parameter} of the form +\begin{ncsimplebnf} +\terminal{suffix (} \opt{pp-balanced-token-seq} \terminal{)} +\end{ncsimplebnf} +shall appear at most once in the \grammarterm{embed-parameter-seq}. + +\pnum +If the resource is empty, this \grammarterm{embed-parameter} is ignored. +Otherwise, the \grammarterm{pp-balanced-token-seq} is placed immediately after +the comma-delimited list of the integral constant expressions. + +\begin{example} +\begin{codeblock} +constexpr unsigned char whl[] = { +#embed "ches.glsl" \ + prefix(0xEF, 0xBB, 0xBF, ) /* a sequence of bytes */ \ + suffix(,) + 0 +}; +// always null-terminated, contains the sequence if not empty +constexpr bool is_empty = sizeof(whl) == 1 && whl[0] == '\0'; +constexpr bool is_not_empty = sizeof(whl) >= 4 + && whl[sizeof(whl) - 1] == '\0' + && whl[0] == '\xEF' && whl[1] == '\xBB' && whl[2] == '\xBF'; +static_assert(is_empty || is_not_empty); +\end{codeblock} +\end{example} + +\rSec3[cpp.embed.param.if.empty]{\tcode{if_empty} parameter} +\pnum +An embed-parameter of the form +\begin{ncsimplebnf} +\terminal{if_empty (} \opt{pp-balanced-token-seq} \terminal{)} +\end{ncsimplebnf} +shall appear at most once in the \grammarterm{embed-parameter-seq}. + +\pnum +If the resource is not empty, this \grammarterm{embed-parameter} is ignored. +Otherwise, the \tcode{\#embed} directive is replaced by the +\grammarterm{pp-balanced-token-seq}. + +\begin{example} +\tcode{limit(0)} affects when a resource is considered empty. +Therefore, the following program: + +\begin{codeblock} +#embed \ + if_empty(42203) limit(0) +\end{codeblock} +expands to +\begin{codeblock} +42203 +\end{codeblock} +\end{example} + +\begin{example} +This resource is considered empty due to the \tcode{limit(0)} \grammarterm{embed-parameter}, +always, including in \tcode{__has_embed} clauses. + +\begin{codeblock} +int infinity_zero () { +#if __has_embed( limit(0) prefix(some tokens)) == __STDC_EMBED_EMPTY__ + // if \tcode{} exists, this conditional inclusion branch is taken and the function returns \tcode{0}. + return 0; +#else + // otherwise, the resource does not exist +#error "The resource does not exist" +#endif +} +\end{codeblock} +\end{example} + \rSec1[cpp.module]{Module directive} \indextext{preprocessing directive!module}% @@ -756,7 +1193,7 @@ \pnum A \grammarterm{pp-module} shall not appear in a context where \tcode{module} -or (if it is the first token of the \grammarterm{pp-module}) \tcode{export} +or (if it is the first preprocessing token of the \grammarterm{pp-module}) \tcode{export} is an identifier defined as an object-like macro. \pnum @@ -817,7 +1254,7 @@ \pnum A \grammarterm{pp-import} shall not appear in a context where \tcode{import} -or (if it is the first token of the \grammarterm{pp-import}) \tcode{export} +or (if it is the first preprocessing token of the \grammarterm{pp-import}) \tcode{export} is an identifier defined as an object-like macro. \pnum @@ -912,8 +1349,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. @@ -1202,7 +1639,7 @@ For each parameter in the replacement list that is neither preceded by a \tcode{\#} or \tcode{\#\#} preprocessing token nor followed by a \tcode{\#\#} preprocessing token, the preprocessing tokens -naming the parameter are replaced by a token sequence determined as follows: +naming the parameter are replaced by a preprocessing token sequence determined as follows: \begin{itemize} \item If the parameter is of the form \grammarterm{va-opt-replacement}, @@ -1215,7 +1652,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. + translation unit with no other preprocessing tokens being available. \end{itemize} \begin{example} \begin{codeblock} @@ -1408,7 +1845,7 @@ \end{note} If the result is not a valid preprocessing token, the behavior is undefined. -The resulting token is available for further macro replacement. +The resulting preprocessing token is available for further macro replacement. The order of evaluation of \tcode{\#\#} operators is unspecified. @@ -1451,7 +1888,7 @@ "hello, world" \end{codeblock} -Space around the \tcode{\#} and \tcode{\#\#} tokens in the macro definition +Space around the \tcode{\#} and \tcode{\#\#} preprocessing tokens in the macro definition is optional. \end{example} @@ -1477,8 +1914,8 @@ "x ## y" \end{codeblock} -In other words, expanding \tcode{hash_hash} produces a new token, -consisting of two adjacent sharp signs, but this new token is not the +In other words, expanding \tcode{hash_hash} produces a new preprocessing token, +consisting of two adjacent sharp signs, but this new preprocessing token is not the \tcode{\#\#} operator. \end{example} @@ -1600,10 +2037,12 @@ \pnum The \defn{line number} -of the current source line is one greater than +of the current source line is +the line number of the current physical source line, +i.e., it is one greater than the number of new-line characters read or introduced in translation phase 1\iref{lex.phases} -while processing the source file to the current token. +while processing the source file to the current preprocessing token. \pnum A preprocessing directive of the form @@ -1704,7 +2143,7 @@ \xname{cplusplus}\\ The integer literal \tcode{\cppver}. \begin{note} -Future revisions of \Cpp{} will +Future revisions of this document will replace the value of this macro with a greater value. \end{note} @@ -1712,7 +2151,7 @@ The macros defined in \tref{cpp.predefined.ft} shall be defined to the corresponding integer literal. \begin{note} -Future revisions of \Cpp{} might replace +Future revisions of this document might replace the values of these macros with greater values. \end{note} @@ -1751,6 +2190,16 @@ The presumed line number can be changed by the \tcode{\#line} directive. \end{footnote} +\item +\indextext{stdc__embed_not_found__@\mname{STDC_EMBED_NOT_FOUND}}% +\indextext{stdc__embed_found__@\mname{STDC_EMBED_FOUND}}% +\indextext{stdc__embed_empty__@\mname{STDC_EMBED_EMPTY}}% +\mname{STDC_EMBED_NOT_FOUND}, \mname{STDC_EMBED_FOUND}, and \mname{STDC_EMBED_EMPTY}\\ +The integer literals \tcode{0}, \tcode{1}, and \tcode{2}, respectively. +\begin{note} +These represent values replaced from \grammarterm{has-embed-expression}{s}\iref{cpp.cond}. +\end{note} + \item \indextext{__stdc_hosted__@\mname{STDC_HOSTED}}% \indextext{implementation!hosted}% @@ -1778,7 +2227,7 @@ \mname{STDCPP_FLOAT16_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports -the ISO/IEC/IEEE 60559 floating-point interchange format binary16 +the \IsoFloatUndated{} floating-point interchange format binary16 as an extended floating-point type\iref{basic.extended.fp}. \item @@ -1786,7 +2235,7 @@ \mname{STDCPP_FLOAT32_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports -the ISO/IEC/IEEE 60559 floating-point interchange format binary32 +the \IsoFloatUndated{} floating-point interchange format binary32 as an extended floating-point type. \item @@ -1794,7 +2243,7 @@ \mname{STDCPP_FLOAT64_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports -the ISO/IEC/IEEE 60559 floating-point interchange format binary64 +the \IsoFloatUndated{} floating-point interchange format binary64 as an extended floating-point type. \item @@ -1802,7 +2251,7 @@ \mname{STDCPP_FLOAT128_T}\\ Defined as the integer literal \tcode{1} if and only if the implementation supports -the ISO/IEC/IEEE 60559 floating-point interchange format binary128 +the \IsoFloatUndated{} floating-point interchange format binary128 as an extended floating-point type. \item @@ -1848,11 +2297,13 @@ \defnxname{cpp_char8_t} & \tcode{202207L} \\ \rowsep \defnxname{cpp_concepts} & \tcode{202002L} \\ \rowsep \defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep -\defnxname{cpp_constexpr} & \tcode{202306L} \\ \rowsep +\defnxname{cpp_constexpr} & \tcode{202406L} \\ \rowsep \defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_constexpr_exceptions} & \tcode{202411L} \\ \rowsep \defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep \defnxname{cpp_consteval} & \tcode{202211L} \\ \rowsep \defnxname{cpp_constinit} & \tcode{201907L} \\ \rowsep +\defnxname{cpp_contracts} & \tcode{202502L} \\ \rowsep \defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep \defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep \defnxname{cpp_deduction_guides} & \tcode{201907L} \\ \rowsep @@ -1886,6 +2337,7 @@ \defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep \defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep \defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep +\defnxname{cpp_pp_embed} & \tcode{202502L} \\ \rowsep \defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep \defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep \defnxname{cpp_ref_qualifiers} & \tcode{200710L} \\ \rowsep @@ -1895,9 +2347,12 @@ \defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep \defnxname{cpp_static_assert} & \tcode{202306L} \\ \rowsep \defnxname{cpp_static_call_operator} & \tcode{202207L} \\ \rowsep -\defnxname{cpp_structured_bindings} & \tcode{202403L} \\ \rowsep +\defnxname{cpp_structured_bindings} & \tcode{202411L} \\ \rowsep +\defnxname{cpp_template_parameters} & \tcode{202502L} \\ \rowsep \defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep \defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep +\defnxname{cpp_trivial_relocatability} & \tcode{202502L} \\ \rowsep +\defnxname{cpp_trivial_union} & \tcode{202502L} \\ \rowsep \defnxname{cpp_unicode_characters} & \tcode{200704L} \\ \rowsep \defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep \defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep diff --git a/source/ranges.tex b/source/ranges.tex index 415826deeb..c16eba7f10 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -27,6 +27,7 @@ \indexheader{ranges}% \indexlibraryglobal{all_t}% \begin{codeblock} +// mostly freestanding #include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} #include // see \ref{iterator.synopsis} @@ -34,170 +35,174 @@ namespace std::ranges { inline namespace @\unspec@ { // \ref{range.access}, range access - inline constexpr @\unspec@ begin = @\unspec@; // freestanding - inline constexpr @\unspec@ end = @\unspec@; // freestanding - inline constexpr @\unspec@ cbegin = @\unspec@; // freestanding - inline constexpr @\unspec@ cend = @\unspec@; // freestanding - inline constexpr @\unspec@ rbegin = @\unspec@; // freestanding - inline constexpr @\unspec@ rend = @\unspec@; // freestanding - inline constexpr @\unspec@ crbegin = @\unspec@; // freestanding - inline constexpr @\unspec@ crend = @\unspec@; // freestanding - - inline constexpr @\unspec@ size = @\unspec@; // freestanding - inline constexpr @\unspec@ ssize = @\unspec@; // freestanding - inline constexpr @\unspec@ empty = @\unspec@; // freestanding - inline constexpr @\unspec@ data = @\unspec@; // freestanding - inline constexpr @\unspec@ cdata = @\unspec@; // freestanding + inline constexpr @\unspec@ begin = @\unspec@; + inline constexpr @\unspec@ end = @\unspec@; + inline constexpr @\unspec@ cbegin = @\unspec@; + inline constexpr @\unspec@ cend = @\unspec@; + inline constexpr @\unspec@ rbegin = @\unspec@; + inline constexpr @\unspec@ rend = @\unspec@; + inline constexpr @\unspec@ crbegin = @\unspec@; + inline constexpr @\unspec@ crend = @\unspec@; + + inline constexpr @\unspec@ size = @\unspec@; + inline constexpr @\unspec@ reserve_hint = @\unspec@; + inline constexpr @\unspec@ ssize = @\unspec@; + inline constexpr @\unspec@ empty = @\unspec@; + inline constexpr @\unspec@ data = @\unspec@; + inline constexpr @\unspec@ cdata = @\unspec@; } // \ref{range.range}, ranges template - concept range = @\seebelow@; // freestanding + concept range = @\seebelow@; template - constexpr bool enable_borrowed_range = false; // freestanding + constexpr bool enable_borrowed_range = false; template - concept borrowed_range = @\seebelow@; // freestanding + concept borrowed_range = @\seebelow@; template - using iterator_t = decltype(ranges::begin(declval())); // freestanding + using iterator_t = decltype(ranges::begin(declval())); template<@\libconcept{range}@ R> - using sentinel_t = decltype(ranges::end(declval())); // freestanding + using sentinel_t = decltype(ranges::end(declval())); template<@\libconcept{range}@ R> - using const_iterator_t = decltype(ranges::cbegin(declval())); // freestanding + using const_iterator_t = decltype(ranges::cbegin(declval())); template<@\libconcept{range}@ R> - using const_sentinel_t = decltype(ranges::cend(declval())); // freestanding + using const_sentinel_t = decltype(ranges::cend(declval())); template<@\libconcept{range}@ R> - using range_difference_t = iter_difference_t>; // freestanding + using range_difference_t = iter_difference_t>; template<@\libconcept{sized_range}@ R> - using range_size_t = decltype(ranges::size(declval())); // freestanding + using range_size_t = decltype(ranges::size(declval())); template<@\libconcept{range}@ R> - using range_value_t = iter_value_t>; // freestanding + using range_value_t = iter_value_t>; template<@\libconcept{range}@ R> - using range_reference_t = iter_reference_t>; // freestanding + using range_reference_t = iter_reference_t>; template<@\libconcept{range}@ R> - using range_const_reference_t = iter_const_reference_t>; // freestanding + using range_const_reference_t = iter_const_reference_t>; template<@\libconcept{range}@ R> - using range_rvalue_reference_t = iter_rvalue_reference_t>; // freestanding + using range_rvalue_reference_t = iter_rvalue_reference_t>; template<@\libconcept{range}@ R> - using range_common_reference_t = iter_common_reference_t>; // freestanding + using range_common_reference_t = iter_common_reference_t>; // \ref{range.sized}, sized ranges template - constexpr bool disable_sized_range = false; // freestanding + constexpr bool disable_sized_range = false; template - concept sized_range = @\seebelow@; // freestanding + concept approximately_sized_range = @\seebelow@; + + template + concept sized_range = @\seebelow@; // \ref{range.view}, views template - constexpr bool enable_view = @\seebelow@; // freestanding + constexpr bool enable_view = @\seebelow@; - struct view_base {}; // freestanding + struct view_base {}; template - concept view = @\seebelow@; // freestanding + concept view = @\seebelow@; // \ref{range.refinements}, other range refinements template - concept output_range = @\seebelow@; // freestanding + concept output_range = @\seebelow@; template - concept input_range = @\seebelow@; // freestanding + concept input_range = @\seebelow@; template - concept forward_range = @\seebelow@; // freestanding + concept forward_range = @\seebelow@; template - concept bidirectional_range = @\seebelow@; // freestanding + concept bidirectional_range = @\seebelow@; template - concept random_access_range = @\seebelow@; // freestanding + concept random_access_range = @\seebelow@; template - concept contiguous_range = @\seebelow@; // freestanding + concept contiguous_range = @\seebelow@; template - concept common_range = @\seebelow@; // freestanding + concept common_range = @\seebelow@; template - concept viewable_range = @\seebelow@; // freestanding + concept viewable_range = @\seebelow@; template - concept constant_range = @\seebelow@; // freestanding + concept constant_range = @\seebelow@; // \ref{view.interface}, class template \tcode{view_interface} template requires is_class_v && @\libconcept{same_as}@> - class view_interface; // freestanding + class view_interface; // \ref{range.subrange}, sub-ranges - enum class @\libglobal{subrange_kind}@ : bool { @\libmember{unsized}{subrange_kind}@, @\libmember{sized}{subrange_kind}@ }; // freestanding + enum class @\libglobal{subrange_kind}@ : bool { @\libmember{unsized}{subrange_kind}@, @\libmember{sized}{subrange_kind}@ }; template<@\libconcept{input_or_output_iterator}@ I, @\libconcept{sentinel_for}@ S = I, subrange_kind K = @\seebelow@> requires (K == subrange_kind::sized || !@\libconcept{sized_sentinel_for}@) - class subrange; // freestanding + class subrange; template - constexpr bool @\libspec{enable_borrowed_range}{subrange}@> = true; // freestanding + constexpr bool @\libspec{enable_borrowed_range}{subrange}@> = true; template requires ((N == 0 && @\libconcept{copyable}@) || N == 1) - constexpr auto get(const subrange& r); // freestanding + constexpr auto get(const subrange& r); template requires (N < 2) - constexpr auto get(subrange&& r); // freestanding + constexpr auto get(subrange&& r); } namespace std { - using ranges::get; // freestanding + using ranges::get; } namespace std::ranges { // \ref{range.dangling}, dangling iterator handling - struct dangling; // freestanding + struct dangling; // \ref{range.elementsof}, class template \tcode{elements_of} template<@\libconcept{range}@ R, class Allocator = allocator> - struct elements_of; + struct elements_of; // hosted template<@\libconcept{range}@ R> - using borrowed_iterator_t = @\seebelow@; // freestanding + using borrowed_iterator_t = @\seebelow@; template<@\libconcept{range}@ R> - using borrowed_subrange_t = @\seebelow@; // freestanding + using borrowed_subrange_t = @\seebelow@; // \ref{range.utility.conv}, range conversions template requires (!@\libconcept{view}@) - constexpr C to(R&& r, Args&&... args); // freestanding + constexpr C to(R&& r, Args&&... args); template class C, @\libconcept{input_range}@ R, class... Args> - constexpr auto to(R&& r, Args&&... args); // freestanding + constexpr auto to(R&& r, Args&&... args); template requires (!@\libconcept{view}@) - constexpr auto to(Args&&... args); // freestanding + constexpr auto to(Args&&... args); template class C, class... Args> - constexpr auto to(Args&&... args); // freestanding + constexpr auto to(Args&&... args); // \ref{range.empty}, empty view template requires is_object_v - class empty_view; // freestanding + class empty_view; template - constexpr bool @\libspec{enable_borrowed_range}{empty_view}@> = true; // freestanding + constexpr bool @\libspec{enable_borrowed_range}{empty_view}@> = true; namespace views { template - constexpr empty_view @\libmember{empty}{views}@{}; // freestanding + constexpr empty_view @\libmember{empty}{views}@{}; } // \ref{range.single}, single view template<@\libconcept{move_constructible}@ T> requires is_object_v - class single_view; // freestanding + class single_view; - namespace views { inline constexpr @\unspecnc@ single = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ single = @\unspecnc@; } template using @\exposidnc{maybe-const}@ = conditional_t; // \expos @@ -205,145 +210,142 @@ // \ref{range.iota}, iota view template<@\libconcept{weakly_incrementable}@ W, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires @\exposconcept{weakly-equality-comparable-with}@ && @\libconcept{copyable}@ - class iota_view; // freestanding + class iota_view; template - constexpr bool @\libspec{enable_borrowed_range}{iota_view}@> = true; // freestanding + constexpr bool @\libspec{enable_borrowed_range}{iota_view}@> = true; - namespace views { inline constexpr @\unspecnc@ iota = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ iota = @\unspecnc@; } // \ref{range.repeat}, repeat view template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound = unreachable_sentinel_t> requires @\seebelow@ - class repeat_view; // freestanding + class repeat_view; - namespace views { inline constexpr @\unspecnc@ repeat = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ repeat = @\unspecnc@; } // \ref{range.istream}, istream view template<@\libconcept{movable}@ Val, class CharT, class Traits = char_traits> requires @\seebelow@ - class basic_istream_view; + class basic_istream_view; // hosted template - using istream_view = basic_istream_view; + using istream_view = basic_istream_view; // hosted template - using wistream_view = basic_istream_view; + using wistream_view = basic_istream_view; // hosted - namespace views { template constexpr @\unspecnc@ istream = @\unspecnc@; } + namespace views { + template constexpr @\unspecnc@ istream = @\unspecnc@; // hosted + } // \ref{range.adaptor.object}, range adaptor objects template requires is_class_v && @\libconcept{same_as}@> - class range_adaptor_closure { }; // freestanding + class range_adaptor_closure { }; // \ref{range.all}, all view namespace views { - inline constexpr @\unspecnc@ all = @\unspecnc@; // freestanding + inline constexpr @\unspecnc@ all = @\unspecnc@; template<@\libconcept{viewable_range}@ R> - using all_t = decltype(all(declval())); // freestanding + using all_t = decltype(all(declval())); } // \ref{range.ref.view}, ref view template<@\libconcept{range}@ R> requires is_object_v - class ref_view; // freestanding + class ref_view; template - constexpr bool @\libspec{enable_borrowed_range}{ref_view}@> = true; // freestanding + constexpr bool @\libspec{enable_borrowed_range}{ref_view}@> = true; // \ref{range.owning.view}, owning view template<@\libconcept{range}@ R> requires @\seebelow@ - class owning_view; // freestanding + class owning_view; template - constexpr bool @\libspec{enable_borrowed_range}{owning_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{owning_view}@> = enable_borrowed_range; // \ref{range.as.rvalue}, as rvalue view template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_rvalue_view; // freestanding + class as_rvalue_view; template - constexpr bool @\libspec{enable_borrowed_range}{as_rvalue_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{as_rvalue_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // \ref{range.filter}, filter view template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{view}@ && is_object_v - class filter_view; // freestanding + class filter_view; - namespace views { inline constexpr @\unspecnc@ filter = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ filter = @\unspecnc@; } // \ref{range.transform}, transform view template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> requires @\libconcept{view}@ && is_object_v && @\libconcept{regular_invocable}@> && @\exposconcept{can-reference}@>> - class transform_view; // freestanding + class transform_view; - namespace views { inline constexpr @\unspecnc@ transform = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ transform = @\unspecnc@; } // \ref{range.take}, take view - template<@\libconcept{view}@> class take_view; // freestanding + template<@\libconcept{view}@> class take_view; template - constexpr bool @\libspec{enable_borrowed_range}{take_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{take_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ take = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ take = @\unspecnc@; } // \ref{range.take.while}, take while view template<@\libconcept{view}@ V, class Pred> requires @\libconcept{input_range}@ && is_object_v && @\libconcept{indirect_unary_predicate}@> - class take_while_view; // freestanding + class take_while_view; - namespace views { inline constexpr @\unspecnc@ take_while = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ take_while = @\unspecnc@; } // \ref{range.drop}, drop view template<@\libconcept{view}@ V> - class drop_view; // freestanding + class drop_view; template - constexpr bool @\libspec{enable_borrowed_range}{drop_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{drop_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ drop = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ drop = @\unspecnc@; } // \ref{range.drop.while}, drop while view template<@\libconcept{view}@ V, class Pred> requires @\libconcept{input_range}@ && is_object_v && @\libconcept{indirect_unary_predicate}@> - class drop_while_view; // freestanding + class drop_while_view; template - constexpr bool @\libspec{enable_borrowed_range}{drop_while_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{drop_while_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ drop_while = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ drop_while = @\unspecnc@; } // \ref{range.join}, join view template<@\libconcept{input_range}@ V> requires @\libconcept{view}@ && @\libconcept{input_range}@> - class join_view; // freestanding + class join_view; - namespace views { inline constexpr @\unspecnc@ join = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ join = @\unspecnc@; } // \ref{range.join.with}, join with view - template - concept @\exposconcept{compatible-joinable-ranges}@ = @\seebelow@; // \expos - template<@\libconcept{input_range}@ V, @\libconcept{forward_range}@ Pattern> - requires @\libconcept{view}@ && @\libconcept{input_range}@> - && @\libconcept{view}@ - && @\exposconcept{compatible-joinable-ranges}@, Pattern> - class join_with_view; // freestanding + requires @\seebelow@ + class join_with_view; - namespace views { inline constexpr @\unspecnc@ join_with = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ join_with = @\unspecnc@; } // \ref{range.lazy.split}, lazy split view template @@ -353,17 +355,17 @@ requires @\libconcept{view}@ && @\libconcept{view}@ && @\libconcept{indirectly_comparable}@, iterator_t, ranges::equal_to> && (@\libconcept{forward_range}@ || @\exposconcept{tiny-range}@) - class lazy_split_view; // freestanding + class lazy_split_view; // \ref{range.split}, split view - template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> - requires @\libconcept{view}@ && @\libconcept{view}@ && - @\libconcept{indirectly_comparable}@, iterator_t, ranges::equal_to> - class split_view; // freestanding + template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> + requires @\libconcept{view}@ && @\libconcept{view}@ && + @\libconcept{indirectly_comparable}@, iterator_t, ranges::equal_to> + class split_view; namespace views { - inline constexpr @\unspecnc@ lazy_split = @\unspecnc@; // freestanding - inline constexpr @\unspecnc@ split = @\unspecnc@; // freestanding + inline constexpr @\unspecnc@ lazy_split = @\unspecnc@; + inline constexpr @\unspecnc@ split = @\unspecnc@; } // \ref{range.concat}, concat view @@ -374,34 +376,34 @@ namespace views { inline constexpr @\unspecnc@ concat = @\unspecnc@; } // \ref{range.counted}, counted view - namespace views { inline constexpr @\unspecnc@ counted = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ counted = @\unspecnc@; } // \ref{range.common}, common view template<@\libconcept{view}@ V> requires (!@\libconcept{common_range}@ && @\libconcept{copyable}@>) - class common_view; // freestanding + class common_view; template - constexpr bool @\libspec{enable_borrowed_range}{common_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{common_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ common = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ common = @\unspecnc@; } // \ref{range.reverse}, reverse view template<@\libconcept{view}@ V> requires @\libconcept{bidirectional_range}@ - class reverse_view; // freestanding + class reverse_view; template - constexpr bool @\libspec{enable_borrowed_range}{reverse_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{reverse_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ reverse = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ reverse = @\unspecnc@; } // \ref{range.as.const}, as const view template<@\libconcept{input_range}@ R> constexpr auto& @\exposid{possibly-const-range}@(R& r) noexcept { // \expos - if constexpr (@\libconcept{constant_range}@ && !@\libconcept{constant_range}@) { + if constexpr (@\libconcept{input_range}@) { return const_cast(r); } else { return r; @@ -410,172 +412,190 @@ template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class as_const_view; // freestanding + class as_const_view; template - constexpr bool @\libspec{enable_borrowed_range}{as_const_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{as_const_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ as_const = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ as_const = @\unspecnc@; } // \ref{range.elements}, elements view template<@\libconcept{input_range}@ V, size_t N> requires @\seebelow@ - class elements_view; // freestanding + class elements_view; template - constexpr bool @\libspec{enable_borrowed_range}{elements_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{elements_view}@> = enable_borrowed_range; template - using @\libglobal{keys_view}@ = elements_view; // freestanding + using @\libglobal{keys_view}@ = elements_view; template - using @\libglobal{values_view}@ = elements_view; // freestanding + using @\libglobal{values_view}@ = elements_view; namespace views { template - constexpr @\unspecnc@ elements = @\unspecnc@; // freestanding - inline constexpr auto @\libmember{keys}{views}@ = elements<0>; // freestanding - inline constexpr auto @\libmember{values}{views}@ = elements<1>; // freestanding + constexpr @\unspecnc@ elements = @\unspecnc@; + inline constexpr auto @\libmember{keys}{views}@ = elements<0>; + inline constexpr auto @\libmember{values}{views}@ = elements<1>; } // \ref{range.enumerate}, enumerate view template<@\libconcept{view}@ V> requires @\seebelow@ - class enumerate_view; // freestanding + class enumerate_view; template - constexpr bool @\libspec{enable_borrowed_range}{enumerate_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{enumerate_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ enumerate = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ enumerate = @\unspecnc@; } // \ref{range.zip}, zip view template<@\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) - class zip_view; // freestanding + class zip_view; template - constexpr bool @\libspec{enable_borrowed_range}{zip_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{zip_view}@> = (enable_borrowed_range && ...); - namespace views { inline constexpr @\unspecnc@ zip = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ zip = @\unspecnc@; } // \ref{range.zip.transform}, zip transform view template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> requires (@\libconcept{view}@ && ...) && (sizeof...(Views) > 0) && is_object_v && @\libconcept{regular_invocable}@...> && @\exposconcept{can-reference}@...>> - class zip_transform_view; // freestanding + class zip_transform_view; - namespace views { inline constexpr @\unspecnc@ zip_transform = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ zip_transform = @\unspecnc@; } // \ref{range.adjacent}, adjacent view template<@\libconcept{forward_range}@ V, size_t N> requires @\libconcept{view}@ && (N > 0) - class adjacent_view; // freestanding + class adjacent_view; template - constexpr bool @\libspec{enable_borrowed_range}{adjacent_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{adjacent_view}@> = enable_borrowed_range; namespace views { template - constexpr @\unspecnc@ adjacent = @\unspecnc@; // freestanding - inline constexpr auto @\libmember{pairwise}{views}@ = adjacent<2>; // freestanding + constexpr @\unspecnc@ adjacent = @\unspecnc@; + inline constexpr auto @\libmember{pairwise}{views}@ = adjacent<2>; } // \ref{range.adjacent.transform}, adjacent transform view template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> requires @\seebelow@ - class adjacent_transform_view; // freestanding + class adjacent_transform_view; namespace views { template - constexpr @\unspecnc@ adjacent_transform = @\unspecnc@; // freestanding - inline constexpr auto @\libmember{pairwise_transform}{views}@ = adjacent_transform<2>; // freestanding + constexpr @\unspecnc@ adjacent_transform = @\unspecnc@; + inline constexpr auto @\libmember{pairwise_transform}{views}@ = adjacent_transform<2>; } // \ref{range.chunk}, chunk view template<@\libconcept{view}@ V> requires @\libconcept{input_range}@ - class chunk_view; // freestanding + class chunk_view; template<@\libconcept{view}@ V> requires @\libconcept{forward_range}@ - class chunk_view; // freestanding + class chunk_view; template - constexpr bool @\libspec{enable_borrowed_range}{chunk_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{chunk_view}@> = @\libconcept{forward_range}@ && enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ chunk = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ chunk = @\unspecnc@; } // \ref{range.slide}, slide view template<@\libconcept{forward_range}@ V> requires @\libconcept{view}@ - class slide_view; // freestanding + class slide_view; template - constexpr bool @\libspec{enable_borrowed_range}{slide_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{slide_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ slide = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ slide = @\unspecnc@; } // \ref{range.chunk.by}, chunk by view template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> requires @\libconcept{view}@ && is_object_v - class chunk_by_view; // freestanding + class chunk_by_view; - namespace views { inline constexpr @\unspecnc@ chunk_by = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ chunk_by = @\unspecnc@; } // \ref{range.stride}, stride view template<@\libconcept{input_range}@ V> requires @\libconcept{view}@ - class stride_view; // freestanding + class stride_view; template - constexpr bool @\libspec{enable_borrowed_range}{stride_view}@> = // freestanding + constexpr bool @\libspec{enable_borrowed_range}{stride_view}@> = enable_borrowed_range; - namespace views { inline constexpr @\unspecnc@ stride = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspecnc@ stride = @\unspecnc@; } // \ref{range.cartesian}, cartesian product view template<@\libconcept{input_range}@ First, @\libconcept{forward_range}@... Vs> requires (@\libconcept{view}@ && ... && @\libconcept{view}@) - class cartesian_product_view; // freestanding + class cartesian_product_view; + + namespace views { inline constexpr @\unspecnc@ cartesian_product = @\unspecnc@; } + + // \ref{range.cache.latest}, cache latest view + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class cache_latest_view; - namespace views { inline constexpr @\unspecnc@ cartesian_product = @\unspecnc@; } // freestanding + namespace views { inline constexpr @\unspec@ cache_latest = @\unspec@; } + + // \ref{range.to.input}, to input view + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class to_input_view; + + template + constexpr bool enable_borrowed_range> = + enable_borrowed_range; + + namespace views { inline constexpr @\unspec@ to_input = @\unspec@; } } namespace std { - namespace views = ranges::views; // freestanding + namespace views = ranges::views; - template struct tuple_size; // freestanding - template struct tuple_element; // freestanding + template struct tuple_size; + template struct tuple_element; template - struct tuple_size> // freestanding + struct tuple_size> : integral_constant {}; template - struct tuple_element<0, ranges::subrange> { // freestanding + struct tuple_element<0, ranges::subrange> { using type = I; }; template - struct tuple_element<1, ranges::subrange> { // freestanding + struct tuple_element<1, ranges::subrange> { using type = S; }; template - struct tuple_element<0, const ranges::subrange> { // freestanding + struct tuple_element<0, const ranges::subrange> { using type = I; }; template - struct tuple_element<1, const ranges::subrange> { // freestanding + struct tuple_element<1, const ranges::subrange> { using type = S; }; - struct from_range_t { explicit from_range_t() = default; }; // freestanding - inline constexpr from_range_t from_range{}; // freestanding + struct from_range_t { explicit from_range_t() = default; }; + inline constexpr from_range_t from_range{}; } \end{codeblock} @@ -1082,6 +1102,50 @@ \tcode{ranges::ssize(E)} is expression-equivalent to \tcode{static_cast(ranges::size(t))}. +\rSec2[range.prim.size.hint]{\tcode{ranges::reserve_hint}} +\indexlibraryglobal{reserve_hint}% + +\pnum +The name \tcode{ranges::reserve_hint} denotes +a customization point object\iref{customization.point.object}. + +\pnum +Given a subexpression \tcode{E} with type \tcode{T}, +let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}. +Then: +\begin{itemize} +\item +If \tcode{ranges::size(E)} is a valid expression, +\tcode{ranges::reserve_hint(E)} is expression-equivalent to +\tcode{ranges::size(E)}. +\item +Otherwise, +if \tcode{auto(t.reserve_hint())} is a valid expression of +integer-like type\iref{iterator.concept.winc}, +\tcode{ranges::re\-serve_hint(E)} is expression-equivalent to +\tcode{auto(t.reserve_hint())}. +\item +Otherwise, +if \tcode{T} is a class or enumeration type and +\tcode{auto(reserve_hint(t))} is a valid expression of +integer-like type where +the meaning of \tcode{reserve_hint} is established as-if by +performing argument-dependent lookup only\iref{basic.lookup.argdep}, then +\tcode{ranges::reserve_hint(E)} is expression-equivalent to that expression. +\item +Otherwise, +\tcode{ranges::reserve_hint(E)} is ill-formed. +\end{itemize} +\begin{note} +Diagnosable ill-formed cases above result in substitution failure when +\tcode{ranges::reserve_hint(E)} appears in the immediate context of +a template instantiation. +\end{note} +\begin{note} +Whenever \tcode{ranges::reserve_hint(E)} is a valid expression, +its type is integer-like. +\end{note} + \rSec2[range.prim.empty]{\tcode{ranges::empty}} \indexlibraryglobal{empty}% @@ -1359,17 +1423,58 @@ \end{example} \end{itemdescr} +\rSec2[range.approximately.sized]{Approximately sized ranges} + +\pnum +The \libconcept{approximately_sized_range} concept refines \libconcept{range} +with the requirement that +an approximation of the number of elements in the range +can be determined in amortized constant time using \tcode{ranges::reserve_hint}. + +\begin{itemdecl} +template + concept @\deflibconcept{approximately_sized_range}@ = + @\libconcept{range}@ && requires(T& t) { ranges::reserve_hint(t); }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given an lvalue \tcode{t} of type \tcode{remove_reference_t}, +\tcode{T} models \libconcept{approximately_sized_range} only if +\begin{itemize} +\item +\tcode{ranges::reserve_hint(t)} is amortized \bigoh{1}, +does not modify \tcode{t}, and +has a value that +is not negative and is representable in \tcode{range_difference_t}, and +\item +if \tcode{iterator_t} models \libconcept{forward_iterator}, +\tcode{ranges::reserve_hint(t)} is well-defined +regardless of the evaluation of \tcode{ranges::begin(t)}. +\begin{note} +\tcode{ranges::reserve_hint(t)} is otherwise not required to be well-defined +after evaluating \tcode{ranges::\linebreak begin(t)}. +For example, +it is possible for \tcode{ranges::reserve_hint(t)} to be well-defined for +an \libconceptx{approximate\-ly_sized_range}{approximately_sized_range} whose +iterator type does not model \libconcept{forward_iterator} +only if evaluated before the first call to \tcode{ranges::begin(t)}. +\end{note} +\end{itemize} +\end{itemdescr} + \rSec2[range.sized]{Sized ranges} \pnum -The \libconcept{sized_range} concept refines \libconcept{range} with +The \libconcept{sized_range} concept +refines \libconcept{approximately_sized_range} with the requirement that the number of elements in the range can be determined in amortized constant time using \tcode{ranges::size}. \begin{itemdecl} template concept @\deflibconcept{sized_range}@ = - @\libconcept{range}@ && requires(T& t) { ranges::size(t); }; + @\libconcept{approximately_sized_range}@ && requires(T& t) { ranges::size(t); }; \end{itemdecl} \begin{itemdescr} @@ -1412,7 +1517,7 @@ \pnum \begin{note} -\tcode{disable_sized_range} allows use of range types with the library +\tcode{disable_sized_range} allows use of \libconcept{range} types with the library that satisfy but do not in fact model \libconcept{sized_range}. \end{note} \end{itemdescr} @@ -1433,7 +1538,7 @@ \begin{itemdescr} \pnum -\tcode{T} models \libconcept{view} only if: +\tcode{T} models \libconcept{view} only if \begin{itemize} \item \tcode{T} has \bigoh{1} move construction; and @@ -1509,8 +1614,8 @@ \remarks Pursuant to \ref{namespace.std}, users may specialize \tcode{enable_view} to \tcode{true} -for cv-unqualified program-defined types which model \libconcept{view}, -and \tcode{false} for types which do not. +for cv-unqualified program-defined types that model \libconcept{view}, +and \tcode{false} for types that do not. Such specializations shall be usable in constant expressions\iref{expr.const} and have type \tcode{const bool}. @@ -1627,7 +1732,7 @@ \rSec2[range.utility.helpers]{Helper concepts} \pnum -Many of the types in subclause~\ref{range.utility} are specified in terms of +Many of the types in \ref{range.utility} are specified in terms of the following exposition-only concepts: \begin{codeblock} @@ -1639,7 +1744,7 @@ template concept @\defexposconceptnc{has-arrow}@ = // \expos - @\libconcept{input_iterator}@ && (is_pointer_v || requires(I i) { i.operator->(); }); + @\libconcept{input_iterator}@ && (is_pointer_v || requires(const I i) { i.operator->(); }); template concept @\defexposconceptnc{different-from}@ = // \expos @@ -1857,17 +1962,17 @@ constexpr operator PairLike() const; constexpr I begin() const requires @\libconcept{copyable}@; - [[nodiscard]] constexpr I begin() requires (!@\libconcept{copyable}@); + constexpr I begin() requires (!@\libconcept{copyable}@); constexpr S end() const; constexpr bool empty() const; constexpr @\placeholdernc{make-unsigned-like-t}@> size() const requires (K == subrange_kind::sized); - [[nodiscard]] constexpr subrange next(iter_difference_t n = 1) const & + constexpr subrange next(iter_difference_t n = 1) const & requires @\libconcept{forward_iterator}@; - [[nodiscard]] constexpr subrange next(iter_difference_t n = 1) &&; - [[nodiscard]] constexpr subrange prev(iter_difference_t n = 1) const + constexpr subrange next(iter_difference_t n = 1) &&; + constexpr subrange prev(iter_difference_t n = 1) const requires @\libconcept{bidirectional_iterator}@; constexpr subrange& advance(iter_difference_t n); }; @@ -1986,7 +2091,7 @@ \indexlibrarymember{begin}{subrange}% \begin{itemdecl} -[[nodiscard]] constexpr I begin() requires (!@\libconcept{copyable}@); +constexpr I begin() requires (!@\libconcept{copyable}@); \end{itemdecl} \begin{itemdescr} @@ -2034,7 +2139,7 @@ \indexlibrarymember{next}{subrange}% \begin{itemdecl} -[[nodiscard]] constexpr subrange next(iter_difference_t n = 1) const & +constexpr subrange next(iter_difference_t n = 1) const & requires @\libconcept{forward_iterator}@; \end{itemdecl} @@ -2051,7 +2156,7 @@ \indexlibrarymember{next}{subrange}% \begin{itemdecl} -[[nodiscard]] constexpr subrange next(iter_difference_t n = 1) &&; +constexpr subrange next(iter_difference_t n = 1) &&; \end{itemdecl} \begin{itemdescr} @@ -2066,7 +2171,7 @@ \indexlibrarymember{prev}{subrange}% \begin{itemdecl} -[[nodiscard]] constexpr subrange prev(iter_difference_t n = 1) const +constexpr subrange prev(iter_difference_t n = 1) const requires @\libconcept{bidirectional_iterator}@; \end{itemdecl} @@ -2347,8 +2452,8 @@ \end{itemize} \begin{codeblock} C c(std::forward(args)...); -if constexpr (@\libconcept{sized_range}@ && @\exposid{reservable-container}@) - c.reserve(static_cast>(ranges::size(r))); +if constexpr (@\libconcept{approximately_sized_range}@ && @\exposid{reservable-container}@) + c.reserve(static_cast>(ranges::reserve_hint(r))); ranges::for_each(r, @\exposid{container-append}@(c)); \end{codeblock} \item @@ -2668,7 +2773,8 @@ Given subexpressions \tcode{E} and \tcode{F}, the expressions \tcode{views::iota(E)} and \tcode{views::iota(E, F)} are expression-equivalent to -\tcode{iota_view(E)} and \tcode{iota_view(E, F)}, respectively. +\tcode{iota_view>(E)} and \tcode{iota_view(E, F)}, +respectively. \pnum \begin{example} @@ -2972,6 +3078,7 @@ \rSec3[range.iota.iterator]{Class \tcode{iota_view::\exposid{iterator}}} +\indexlibraryglobal{iota_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{weakly_incrementable}@ W, @\libconcept{semiregular}@ Bound> @@ -3352,6 +3459,7 @@ \rSec3[range.iota.sentinel]{Class \tcode{iota_view::\exposid{sentinel}}} +\indexlibraryglobal{iota_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{weakly_incrementable}@ W, @\libconcept{semiregular}@ Bound> @@ -3590,6 +3698,7 @@ \rSec3[range.repeat.iterator]{Class \tcode{repeat_view::\exposid{iterator}}} +\indexlibraryglobal{repeat_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{move_constructible}@ T, @\libconcept{semiregular}@ Bound> @@ -3893,7 +4002,7 @@ template concept @\defexposconceptnc{stream-extractable}@ = // \expos requires(basic_istream& is, Val& t) { - is >> t; + is >> t; }; template<@\libconcept{movable}@ Val, class CharT, class Traits = char_traits> @@ -3943,6 +4052,7 @@ \rSec3[range.istream.iterator]{Class \tcode{basic_istream_view::\exposid{iterator}}} +\indexlibraryglobal{basic_istream_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{movable}@ Val, class CharT, class Traits> @@ -4233,7 +4343,7 @@ \rSec2[range.nonprop.cache]{Non-propagating cache} \pnum -Some types in subclause \ref{range.adaptors} are specified in terms of +Some types in \ref{range.adaptors} are specified in terms of an exposition-only class template \exposid{non-propagating-\brk{}cache}. \tcode{\exposid{non-propagating-cache}} behaves exactly like \tcode{optional} with the following differences: @@ -4348,7 +4458,6 @@ template concept @\defexposconceptnc{all-forward}@ = // \expos (@\libconcept{forward_range}@<@\exposid{maybe-const}@> && ...); - } \end{codeblock} @@ -4405,6 +4514,9 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(*@\exposid{r_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(*@\exposid{r_}@); } + constexpr auto data() const requires @\libconcept{contiguous_range}@ { return ranges::data(*@\exposid{r_}@); } }; @@ -4445,6 +4557,8 @@ \pnum \tcode{owning_view} is a move-only view of the elements of some other range. + +\indexlibraryglobal{owning_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{range}@ R> @@ -4483,6 +4597,11 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{r_}@); } + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{r_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{r_}@); } + constexpr auto data() requires @\libconcept{contiguous_range}@ { return ranges::data(@\exposid{r_}@); } constexpr auto data() const requires @\libconcept{contiguous_range}@ @@ -4491,6 +4610,7 @@ } \end{codeblock} +\indexlibraryctor{owning_view}% \begin{itemdecl} constexpr owning_view(R&& t); \end{itemdecl} @@ -4520,7 +4640,9 @@ The expression \tcode{views::as_rvalue(E)} is expression-equivalent to: \begin{itemize} \item -\tcode{views::all(E)} if \tcode{\libconcept{same_as}, range_reference_t>} is \tcode{true}. +\tcode{views::all(E)} if +\tcode{T} models \libconcept{input_range} and +\tcode{\libconcept{same_as}, range_reference_t>} is \tcode{true}. \item Otherwise, \tcode{as_rvalue_view(E)}. \end{itemize} @@ -4573,6 +4695,11 @@ constexpr auto size() requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } }; template @@ -4708,6 +4835,7 @@ \rSec3[range.filter.iterator]{Class \tcode{filter_view::\exposid{iterator}}} +\indexlibraryglobal{filter_view::\exposid{iterator}}% \indexlibrarymember{iterator}{filter_view}% \begin{codeblock} namespace std::ranges { @@ -4962,6 +5090,7 @@ \rSec3[range.filter.sentinel]{Class \tcode{filter_view::\exposid{sentinel}}} +\indexlibraryglobal{filter_view::\exposid{sentinel}}% \indexlibrarymember{sentinel}{filter_view}% \begin{codeblock} namespace std::ranges { @@ -5088,6 +5217,11 @@ constexpr auto size() requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } }; template @@ -5199,6 +5333,7 @@ \rSec3[range.transform.iterator]{Class template \tcode{transform_view::\exposid{iterator}}} +\indexlibraryglobal{transform_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> @@ -5582,6 +5717,7 @@ \rSec3[range.transform.sentinel]{Class template \tcode{transform_view::\exposid{sentinel}}} +\indexlibraryglobal{transform_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, @\libconcept{move_constructible}@ F> @@ -5878,6 +6014,22 @@ auto n = ranges::size(@\exposid{base_}@); return ranges::min(n, static_cast(@\exposid{count_}@)); } + + constexpr auto reserve_hint() { + if constexpr (@\libconcept{approximately_sized_range}@) { + auto n = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); + return @\exposid{to-unsigned-like}@(ranges::min(n, @\exposid{count_}@)); + } + return @\exposid{to-unsigned-like}@(@\exposid{count_}@); + } + + constexpr auto reserve_hint() const { + if constexpr (@\libconcept{approximately_sized_range}@) { + auto n = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); + return @\exposid{to-unsigned-like}@(ranges::min(n, @\exposid{count_}@)); + } + return @\exposid{to-unsigned-like}@(@\exposid{count_}@); + } }; template @@ -5904,6 +6056,7 @@ \rSec3[range.take.sentinel]{Class template \tcode{take_view::\exposid{sentinel}}} +\indexlibraryglobal{take_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -6089,6 +6242,7 @@ \rSec3[range.take.while.sentinel]{Class template \tcode{take_while_view::\exposid{sentinel}}} +\indexlibraryglobal{take_while_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V, class Pred> @@ -6288,6 +6442,16 @@ return s < c ? 0 : s - c; } + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ { + const auto s = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); + return @\exposid{to-unsigned-like}@(s < @\exposid{count_}@ ? 0 : s - @\exposid{count_}@); + } + + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ { + const auto s = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); + return @\exposid{to-unsigned-like}@(s < @\exposid{count_}@ ? 0 : s - @\exposid{count_}@); + } + private: V @\exposid{base_}@ = V(); // \expos range_difference_t @\exposid{count_}@ = 0; // \expos @@ -6573,6 +6737,7 @@ \rSec3[range.join.iterator]{Class template \tcode{join_view::\exposid{iterator}}} +\indexlibraryglobal{join_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V> @@ -6673,7 +6838,7 @@ \exposid{Base} models \libconcept{forward_range}, and \tcode{range_reference_t<\exposid{Base}>} models \libconcept{forward_range}. In that case, -\tcode{iterator::iter\-ator_category} is defined as follows: +\tcode{\exposid{iterator}::iter\-ator_category} is defined as follows: \begin{itemize} \item Let \placeholder{OUTERC} denote \tcode{iterator_traits>::iterator_category}, and @@ -6693,7 +6858,7 @@ \end{itemize} \pnum -\tcode{iterator::difference_type} denotes the type: +\tcode{\exposid{iterator}::difference_type} denotes the type: \begin{codeblock} common_type_t< range_difference_t<@\exposid{Base}@>, @@ -6927,6 +7092,7 @@ \rSec3[range.join.sentinel]{Class template \tcode{join_view::\exposid{sentinel}}} +\indexlibraryglobal{join_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V> @@ -6976,7 +7142,6 @@ \end{itemdescr} \indexlibrarymember{operator==}{join_view::\exposid{sentinel}}%3431 - \begin{itemdecl} template requires @\libconcept{sentinel_for}@, iterator_t<@\exposid{maybe-const}@>> @@ -7021,21 +7186,16 @@ \rSec3[range.join.with.view]{Class template \tcode{join_with_view}} +\indexlibraryglobal{join_with_view}% \begin{codeblock} namespace std::ranges { - template - concept @\defexposconcept{compatible-joinable-ranges}@ = // \expos - @\libconcept{common_with}@, range_value_t

> && - @\libconcept{common_reference_with}@, range_reference_t

> && - @\libconcept{common_reference_with}@, range_rvalue_reference_t

>; - template concept @\defexposconcept{bidirectional-common}@ = @\libconcept{bidirectional_range}@ && @\libconcept{common_range}@; // \expos template<@\libconcept{input_range}@ V, @\libconcept{forward_range}@ Pattern> requires @\libconcept{view}@ && @\libconcept{input_range}@> && @\libconcept{view}@ - && @\exposconcept{compatible-joinable-ranges}@, Pattern> + && @\exposconcept{concatable}@, Pattern> class join_with_view : public view_interface> { using @\exposid{InnerRng}@ = range_reference_t; // \expos @@ -7081,7 +7241,8 @@ requires @\libconcept{forward_range}@ && @\libconcept{forward_range}@ && is_reference_v> && - @\libconcept{input_range}@> { + @\libconcept{input_range}@> && + @\exposconcept{concatable}@, const Pattern> { return @\exposid{iterator}@{*this, ranges::begin(@\exposid{base_}@)}; } @@ -7096,7 +7257,8 @@ constexpr auto end() const requires @\libconcept{forward_range}@ && @\libconcept{forward_range}@ && is_reference_v> && - @\libconcept{input_range}@> { + @\libconcept{input_range}@> && + @\exposconcept{concatable}@, const Pattern> { using InnerConstRng = range_reference_t; if constexpr (@\libconcept{forward_range}@ && @\libconcept{common_range}@ && @\libconcept{common_range}@) @@ -7115,6 +7277,7 @@ } \end{codeblock} +\indexlibraryctor{join_with_view}% \begin{itemdecl} constexpr explicit join_with_view(V base, Pattern pattern); \end{itemdecl} @@ -7126,6 +7289,7 @@ \exposid{pattern_} with \tcode{std::move(pattern)}. \end{itemdescr} +\indexlibraryctor{join_with_view}% \begin{itemdecl} template<@\libconcept{input_range}@ R> requires @\libconcept{constructible_from}@> && @@ -7142,11 +7306,12 @@ \rSec3[range.join.with.iterator]{Class template \tcode{join_with_view::\exposid{iterator}}} +\indexlibraryglobal{join_with_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, @\libconcept{forward_range}@ Pattern> requires @\libconcept{view}@ && @\libconcept{input_range}@> - && @\libconcept{view}@ && @\exposconcept{compatible-joinable-ranges}@, Pattern> + && @\libconcept{view}@ && @\exposconcept{concatable}@, Pattern> template class join_with_view::@\exposid{iterator}@ { using @\exposid{Parent}@ = @\exposid{maybe-const}@; // \expos @@ -7264,7 +7429,7 @@ \item Otherwise, if \placeholder{OUTERC}, \placeholder{INNERC}, and \placeholder{PATTERNC} -each model \tcode{\libconcept{derived_from}} +each model \tcode{\libconcept{derived_from}} and \exposid{InnerBase} and \exposid{PatternBase} each model \libconcept{common_range}, \tcode{iterator_cate\-gory} denotes \tcode{bidirectional_iterator_tag}. @@ -7287,9 +7452,9 @@ \tcode{\exposid{iterator}::difference_type} denotes the type: \begin{codeblock} common_type_t< - iter_difference_t<@\exposid{OuterIter}@>, - iter_difference_t<@\exposid{InnerIter}@>, - iter_difference_t<@\exposid{PatternIter}@>> + iter_difference_t<@\exposid{OuterIter}@>, + iter_difference_t<@\exposid{InnerIter}@>, + iter_difference_t<@\exposid{PatternIter}@>> \end{codeblock} \begin{itemdecl} @@ -7419,6 +7584,7 @@ \end{note} \end{itemdescr} +\indexlibrarymember{operator--}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr decltype(auto) operator*() const; \end{itemdecl} @@ -7434,6 +7600,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -7449,6 +7616,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -7459,6 +7627,7 @@ Equivalent to \tcode{++*this}. \end{itemdescr} +\indexlibrarymember{operator++}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int) requires @\exposid{ref-is-glvalue}@ && @\libconcept{forward_iterator}@<@\exposid{OuterIter}@> && @\libconcept{forward_iterator}@<@\exposid{InnerIter}@>; @@ -7475,6 +7644,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\exposid{ref-is-glvalue}@ && @\libconcept{bidirectional_range}@<@\exposid{Base}@> && @@ -7515,6 +7685,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{join_with_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\exposid{ref-is-glvalue}@ && @\libconcept{bidirectional_range}@<@\exposid{Base}@> && @@ -7549,11 +7720,12 @@ \rSec3[range.join.with.sentinel]{Class template \tcode{join_with_view::\exposid{sentinel}}} +\indexlibraryglobal{join_with_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, @\libconcept{forward_range}@ Pattern> requires @\libconcept{view}@ && @\libconcept{input_range}@> - && @\libconcept{view}@ && @\exposconcept{compatible-joinable-ranges}@, Pattern> + && @\libconcept{view}@ && @\exposconcept{concatable}@, Pattern> template class join_with_view::@\exposid{sentinel}@ { using @\exposid{Parent}@ = @\exposid{maybe-const}@; // \expos @@ -8199,6 +8371,7 @@ \rSec3[range.split.view]{Class template \tcode{split_view}} +\indexlibraryglobal{split_view} \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> @@ -8250,6 +8423,7 @@ } \end{codeblock} +\indexlibraryctor{split_view} \begin{itemdecl} constexpr explicit split_view(V base, Pattern pattern); \end{itemdecl} @@ -8276,6 +8450,7 @@ \exposid{pattern_} with \tcode{views::\linebreak single(std::move(e))}. \end{itemdescr} +\indexlibrarymember{begin}{split_view} \begin{itemdecl} constexpr @\exposid{iterator}@ begin(); \end{itemdecl} @@ -8313,6 +8488,7 @@ \rSec3[range.split.iterator]{Class \tcode{split_view::\exposid{iterator}}} +\indexlibraryglobal{split_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> @@ -8345,6 +8521,7 @@ } \end{codeblock} +\indexlibraryctor{split_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(split_view& parent, iterator_t current, subrange> next); \end{itemdecl} @@ -8357,6 +8534,7 @@ \exposid{next_} with \tcode{std::move(next)}. \end{itemdescr} +\indexlibrarymember{base}{split_view::\exposid{iterator}}% \begin{itemdecl} constexpr iterator_t base() const; \end{itemdecl} @@ -8367,6 +8545,7 @@ Equivalent to: \tcode{return \exposid{cur_};} \end{itemdescr} +\indexlibrarymember{operator*}{split_view::\exposid{iterator}}% \begin{itemdecl} constexpr value_type operator*() const; \end{itemdecl} @@ -8377,6 +8556,7 @@ Equivalent to: \tcode{return \{\exposid{cur_}, \exposid{next_}.begin()\};} \end{itemdescr} +\indexlibrarymember{operator++}{split_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -8402,6 +8582,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{split_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -8417,6 +8598,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator==}{split_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); \end{itemdecl} @@ -8432,6 +8614,7 @@ \rSec3[range.split.sentinel]{Class \tcode{split_view::\exposid{sentinel}}} +\indexlibraryglobal{split_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{forward_range}@ Pattern> @@ -8450,6 +8633,7 @@ } \end{codeblock} +\indexlibraryctor{split_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(split_view& parent); \end{itemdecl} @@ -8460,6 +8644,7 @@ Initializes \exposid{end_} with \tcode{ranges::end(parent.\exposid{base_})}. \end{itemdescr} +\indexlibrarymember{operator==}{split_view::\exposid{sentinel}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); \end{itemdecl} @@ -8483,7 +8668,8 @@ Given a pack of subexpressions \tcode{Es...}, the expression \tcode{views::concat(Es...)} is expression-equivalent to \begin{itemize} -\item \tcode{views::all(Es...)} if \tcode{Es} is a pack with only one element, +\item \tcode{views::all(Es...)} if \tcode{Es} is a pack with only one element +whose type models \libconcept{input_range}, \item otherwise, \tcode{concat_view(Es...)}. \end{itemize} \begin{example} @@ -8658,12 +8844,12 @@ \begin{itemdescr} \pnum \effects -Let \tcode{is-const} be +Let \exposid{is-const} be \tcode{true} for the const-qualified overload, and \tcode{false} otherwise. Equivalent to: \begin{codeblock} -@\exposid{iterator}@ it(this, in_place_index<0>, ranges::begin(std::get<0>(@\exposid{views_}@))); +@\exposid{iterator}@<@\exposid{is-const}@> it(this, in_place_index<0>, ranges::begin(std::get<0>(@\exposid{views_}@))); it.template @\exposid{satisfy}@<0>(); return it; \end{codeblock} @@ -8679,14 +8865,14 @@ \begin{itemdescr} \pnum \effects -Let \tcode{is-const} be +Let \exposid{is-const} be \tcode{true} for the const-qualified overload, and \tcode{false} otherwise. Equivalent to: \begin{codeblock} constexpr auto N = sizeof...(Views); -if constexpr (@\libconcept{common_range}@<@\exposid{maybe-const}@>) { - return @\exposid{iterator}@(this, in_place_index, +if constexpr (@\libconcept{common_range}@<@\exposid{maybe-const}@<@\exposid{is-const}@, Views...[N - 1]>>) { + return @\exposid{iterator}@<@\exposid{is-const}@>(this, in_place_index, ranges::end(std::get(@\exposid{views_}@))); } else { return default_sentinel; @@ -8717,6 +8903,7 @@ \rSec3[range.concat.iterator]{Class \tcode{concat_view::\exposid{iterator}}} \indexlibrarymember{iterator}{concat_view}% +\indexlibraryglobal{concat_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@... Views> @@ -8758,7 +8945,7 @@ public: @\exposid{iterator}@() = default; - constexpr @\exposid{iterator}@(iterator i) + constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); constexpr decltype(auto) operator*() const; @@ -8855,7 +9042,7 @@ \tcode{iterator_category} denotes \tcode{random_access_iterator_tag}. \item Otherwise, if -\tcode{(\libconcept{derived_from} \&\& ...) \&\& \exposconceptx{concat-is--\linebreak{}bidirectional}{concat-is-bidirectional}} +\tcode{(\libconcept{derived_from} \&\& ...) \&\& \exposconceptx{concat-is-\linebreak{}bidirectional}{concat-is-bidirectional}} is \tcode{true}, \tcode{iterator_category} denotes \tcode{bidirectional_iter\-ator_tag}. \item @@ -8871,7 +9058,7 @@ \indexlibrarymember{\exposid{satisfy}}{concat_view::\exposid{iterator}}% \begin{itemdecl} template - constexpr void @\exposid{satisfy}@(); // \expos + constexpr void @\exposid{satisfy}@(); \end{itemdecl} \begin{itemdescr} @@ -8891,7 +9078,7 @@ \indexlibrarymember{\exposid{prev}}{concat_view::\exposid{iterator}}% \begin{itemdecl} template - constexpr void @\exposid{prev}@(); // \expos + constexpr void @\exposid{prev}@(); \end{itemdecl} \begin{itemdescr} @@ -8915,7 +9102,7 @@ \indexlibrarymember{\exposid{advance-fwd}}{concat_view::\exposid{iterator}}% \begin{itemdecl} template - constexpr void @\exposid{advance-fwd}@(difference_type offset, difference_type steps); // \expos + constexpr void @\exposid{advance-fwd}@(difference_type offset, difference_type steps); \end{itemdecl} \begin{itemdescr} @@ -8941,7 +9128,7 @@ \indexlibrarymember{\exposid{advance-bwd}}{concat_view::\exposid{iterator}}% \begin{itemdecl} template - constexpr void @\exposid{advance-bwd}@(difference_type offset, difference_type steps); // \expos + constexpr void @\exposid{advance-bwd}@(difference_type offset, difference_type steps); \end{itemdecl} \begin{itemdescr} @@ -8967,7 +9154,7 @@ \indexlibraryctor{concat_view::\exposid{iterator}}% \begin{itemdecl} template - constexpr explicit @\exposid{iterator}@(@\exposid{maybe-const}@* parent, // \expos + constexpr explicit @\exposid{iterator}@(@\exposid{maybe-const}@* parent, Args&&... args) requires @\libconcept{constructible_from}@<@\exposid{base-iter}@, Args&&...>; \end{itemdecl} @@ -8987,6 +9174,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{it.\exposid{it_}.valueless_by_exception()} is \tcode{false}. + \pnum \effects Initializes \exposid{parent_} with \tcode{it.\exposid{parent_}}, and @@ -9476,7 +9667,7 @@ \par % This paragraph is part of the \remarks clause. The expression in the \grammarterm{requires-clause} is equivalent to \begin{codeblock} -@\libconcept{swappable_with}@, iter_reference_t> && +@\libconcept{swappable_with}@, iter_reference_t<@\exposid{iterator}@>> && (... && @\libconcept{indirectly_swappable}@>>) \end{codeblock} \end{itemdescr} @@ -9624,6 +9815,13 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ { + return ranges::reserve_hint(@\exposid{base_}@); + } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ { + return ranges::reserve_hint(@\exposid{base_}@); + } }; template @@ -9721,6 +9919,13 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ { + return ranges::reserve_hint(@\exposid{base_}@); + } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ { + return ranges::reserve_hint(@\exposid{base_}@); + } }; template @@ -9839,6 +10044,7 @@ \rSec3[range.as.const.view]{Class template \tcode{as_const_view}} +\indexlibraryglobal{as_const_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -9861,6 +10067,11 @@ constexpr auto size() requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } }; template @@ -9868,6 +10079,7 @@ } \end{codeblock} +\indexlibraryctor{as_const_view::\exposid{iterator}}% \begin{itemdecl} constexpr explicit as_const_view(V base); \end{itemdecl} @@ -9994,6 +10206,12 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + private: // \ref{range.elements.iterator}, class template \tcode{elements_view::\exposid{iterator}} template class @\exposid{iterator}@; // \expos @@ -10019,6 +10237,7 @@ \rSec3[range.elements.iterator]{Class template \tcode{elements_view::\exposid{iterator}}} +\indexlibraryglobal{elements_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, size_t N> @@ -10416,6 +10635,7 @@ \rSec3[range.elements.sentinel]{Class template \tcode{elements_view::\exposid{sentinel}}} +\indexlibraryglobal{elements_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V, size_t N> @@ -10554,6 +10774,7 @@ \rSec3[range.enumerate.view]{Class template \tcode{enumerate_view}} +\indexlibraryglobal{enumerate_view}% \indexlibrarymember{begin}{enumerate_view}% \indexlibrarymember{end}{enumerate_view}% \indexlibrarymember{size}{enumerate_view}% @@ -10599,6 +10820,11 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return ranges::size(@\exposid{base_}@); } + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ + { return ranges::reserve_hint(@\exposid{base_}@); } + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } constexpr V base() && { return std::move(@\exposid{base_}@); } }; @@ -10608,6 +10834,7 @@ } \end{codeblock} +\indexlibraryctor{enumerate_view}% \begin{itemdecl} constexpr explicit enumerate_view(V base); \end{itemdecl} @@ -11112,9 +11339,9 @@ \rSec3[range.zip.view]{Class template \tcode{zip_view}} +\indexlibraryglobal{zip_view}% \indexlibrarymember{begin}{zip_view}% \indexlibrarymember{end}{zip_view}% -\indexlibrarymember{size}{zip_view}% \begin{codeblock} namespace std::ranges { template @@ -11184,6 +11411,7 @@ is not required to produce meaningful results\iref{iterator.concept.forward}. \end{note} +\indexlibraryctor{zip_view}% \begin{itemdecl} constexpr explicit zip_view(Views... views); \end{itemdecl} @@ -11194,6 +11422,7 @@ Initializes \exposid{views_} with \tcode{std::move(views)...}. \end{itemdescr} +\indexlibrarymember{size}{zip_view}% \begin{itemdecl} constexpr auto size() requires (@\libconcept{sized_range}@ && ...); constexpr auto size() const requires (@\libconcept{sized_range}@ && ...); @@ -11213,6 +11442,7 @@ \rSec3[range.zip.iterator]{Class template \tcode{zip_view::\exposid{iterator}}} +\indexlibraryglobal{zip_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@... Views> @@ -11299,6 +11529,7 @@ exits via an exception, the iterator acquires a singular value. +\indexlibraryctor{zip_view::\exposid{iterator}}% \begin{itemdecl} constexpr explicit @\exposid{iterator}@(tuple>...> current); \end{itemdecl} @@ -11309,6 +11540,7 @@ Initializes \exposid{current_} with \tcode{std::move(current)}. \end{itemdescr} +\indexlibraryctor{zip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && (@\libconcept{convertible_to}@, iterator_t> && ...); @@ -11320,6 +11552,7 @@ Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}. \end{itemdescr} +\indexlibrarymember{operator*}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator*() const; \end{itemdecl} @@ -11333,6 +11566,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -11347,6 +11581,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -11357,6 +11592,7 @@ Equivalent to \tcode{++*this}. \end{itemdescr} +\indexlibrarymember{operator++}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int) requires @\exposconcept{all-forward}@; \end{itemdecl} @@ -11372,6 +11608,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\exposconcept{all-bidirectional}@; \end{itemdecl} @@ -11386,6 +11623,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\exposconcept{all-bidirectional}@; \end{itemdecl} @@ -11401,6 +11639,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\exposconcept{all-random-access}@; @@ -11416,6 +11655,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-=}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\exposconcept{all-random-access}@; @@ -11431,6 +11671,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator[]}{izip_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator[](difference_type n) const requires @\exposconcept{all-random-access}@; @@ -11583,6 +11824,7 @@ \rSec3[range.zip.sentinel]{Class template \tcode{zip_view::\exposid{sentinel}}} +\indexlibraryglobal{zip_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@... Views> @@ -11617,6 +11859,7 @@ } \end{codeblock} +\indexlibraryctor{zip_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(tuple>...> end); \end{itemdecl} @@ -11627,6 +11870,7 @@ Initializes \exposid{end_} with \tcode{end}. \end{itemdescr} +\indexlibraryctor{zip_view::\exposid{sentinel}}% \begin{itemdecl} constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) requires Const && (@\libconcept{convertible_to}@, sentinel_t> && ...); @@ -11743,6 +11987,7 @@ \rSec3[range.zip.transform.view]{Class template \tcode{zip_transform_view}} +\indexlibraryglobal{zip_transform_view}% \indexlibrarymember{begin}{zip_transform_view}% \indexlibrarymember{end}{zip_transform_view}% \indexlibrarymember{size}{zip_transform_view}% @@ -11813,6 +12058,7 @@ } \end{codeblock} +\indexlibraryctor{zip_transform_view}% \begin{itemdecl} constexpr explicit zip_transform_view(F fun, Views... views); \end{itemdecl} @@ -11826,6 +12072,7 @@ \rSec3[range.zip.transform.iterator]{Class template \tcode{zip_transform_view::\exposid{iterator}}} +\indexlibraryglobal{zip_transform_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> @@ -11922,6 +12169,7 @@ \end{itemize} \end{itemize} +\indexlibraryctor{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{ziperator}@ inner); \end{itemdecl} @@ -11933,6 +12181,7 @@ \exposid{inner_} with \tcode{std::move(inner)}. \end{itemdescr} +\indexlibraryctor{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@<@\exposid{ziperator}@, @\exposid{ziperator}@>; @@ -11945,6 +12194,7 @@ \exposid{inner_} with \tcode{std::move(i.\exposid{inner_})}. \end{itemdescr} +\indexlibrarymember{operator*}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr decltype(auto) operator*() const noexcept(@\seebelow@); \end{itemdecl} @@ -11961,11 +12211,12 @@ \pnum \remarks -Let \tcode{Is} be the pack \tcode{0, 1, \ldots, \tcode{(sizeof...(Views)-1)}}. +Let \tcode{Is} be the pack \tcode{0, 1, \ldots, \tcode{(sizeof...(Views) - 1)}}. The exception specification is equivalent to: \tcode{noexcept(invoke(*\exposid{parent_}->\exposid{fun_}, *std::get(\exposid{inner_}.\exposid{current_})...))}. \end{itemdescr} +\indexlibrarymember{operator++}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -11980,6 +12231,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -11990,6 +12242,7 @@ Equivalent to: \tcode{++*this}. \end{itemdescr} +\indexlibrarymember{operator++}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -12005,6 +12258,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -12019,6 +12273,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -12034,6 +12289,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12049,6 +12305,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12064,6 +12321,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator[]}{zip_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr decltype(auto) operator[](difference_type n) const requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12137,6 +12395,7 @@ \rSec3[range.zip.transform.sentinel]{Class template \tcode{zip_transform_view::\exposid{sentinel}}} +\indexlibraryglobal{zip_transform_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{move_constructible}@ F, @\libconcept{input_range}@... Views> @@ -12170,6 +12429,7 @@ } \end{codeblock} +\indexlibraryctor{zip_transform_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(@\exposid{zentinel}@ inner); \end{itemdecl} @@ -12180,6 +12440,7 @@ Initializes \exposid{inner_} with \tcode{inner}. \end{itemdescr} +\indexlibraryctor{zip_transform_view::\exposid{sentinel}}% \begin{itemdecl} constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) requires Const && @\libconcept{convertible_to}@<@\exposid{zentinel}@, @\exposid{zentinel}@>; @@ -12225,7 +12486,6 @@ \rSec3[range.adjacent.overview]{Overview} \pnum -\indexlibraryglobal{adjacent_view}% \tcode{adjacent_view} takes a view and produces a view whose $M^\text{th}$ element is a tuple of references to @@ -12242,7 +12502,8 @@ \begin{itemize} \item \tcode{((void)E, auto(views::empty>))} -if \tcode{N} is equal to \tcode{0}, +if \tcode{N} is equal to \tcode{0} and +\tcode{decltype((E))} models \libconcept{forward_range}, \item otherwise, \tcode{adjacent_view, N>(E)}. \end{itemize} @@ -12263,9 +12524,9 @@ \rSec3[range.adjacent.view]{Class template \tcode{adjacent_view}} +\indexlibraryglobal{adjacent_view}% \indexlibrarymember{begin}{adjacent_view}% \indexlibrarymember{end}{adjacent_view}% -\indexlibrarymember{size}{adjacent_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, size_t N> @@ -12314,10 +12575,14 @@ constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; }; } \end{codeblock} +\indexlibraryctor{adjacent_view}% \begin{itemdecl} constexpr explicit adjacent_view(V base); \end{itemdecl} @@ -12328,6 +12593,7 @@ Initializes \exposid{base_} with \tcode{std::move(base)}. \end{itemdescr} +\indexlibrarymember{size}{adjacent_view}% \begin{itemdecl} constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; @@ -12346,8 +12612,28 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{reserve_hint}{adjacent_view}% +\begin{itemdecl} +constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; +constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +using DT = range_difference_t; +using CT = common_type_t; +auto sz = static_cast(ranges::reserve_hint(@\exposid{base_}@)); +sz -= std::min(sz, N - 1); +return @\exposid{to-unsigned-like}@(sz); +\end{codeblock} +\end{itemdescr} + \rSec3[range.adjacent.iterator]{Class template \tcode{adjacent_view::\exposid{iterator}}} +\indexlibraryglobal{adjacent_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, size_t N> @@ -12430,6 +12716,7 @@ If the invocation of any non-const member function of \exposid{iterator} exits via an exception, the \exposid{iterator} acquires a singular value. +\indexlibraryctor{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(iterator_t<@\exposid{Base}@> first, sentinel_t<@\exposid{Base}@> last); \end{itemdecl} @@ -12443,6 +12730,7 @@ is \tcode{true}. \end{itemdescr} +\indexlibraryctor{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{as-sentinel}@, iterator_t<@\exposid{Base}@> first, iterator_t<@\exposid{Base}@> last); \end{itemdecl} @@ -12458,6 +12746,7 @@ is \tcode{true}. \end{itemdescr} +\indexlibraryctor{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; @@ -12470,6 +12759,7 @@ with the corresponding element of \tcode{i.\exposid{current_}} as an xvalue. \end{itemdescr} +\indexlibrarymember{operator*}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator*() const; \end{itemdecl} @@ -12483,6 +12773,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -12502,6 +12793,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator++}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -12517,6 +12809,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -12536,6 +12829,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator--}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -12551,6 +12845,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12571,6 +12866,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator-=}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12591,6 +12887,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator[]}{adjacent_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator[](difference_type n) const requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -12763,6 +13060,7 @@ \rSec3[range.adjacent.sentinel]{Class template \tcode{adjacent_view::\exposid{sentinel}}} +\indexlibraryglobal{adjacent_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, size_t N> @@ -12795,6 +13093,7 @@ } \end{codeblock} +\indexlibraryctor{adjacent_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(sentinel_t<@\exposid{Base}@> end); \end{itemdecl} @@ -12805,6 +13104,7 @@ Initializes \exposid{end_} with \tcode{end}. \end{itemdescr} +\indexlibraryctor{adjacent_view::\exposid{sentinel}}% \begin{itemdecl} constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) requires Const && @\libconcept{convertible_to}@, sentinel_t<@\exposid{Base}@>>; @@ -12859,7 +13159,6 @@ \rSec3[range.adjacent.transform.overview]{Overview} \pnum -\indexlibraryglobal{adjacent_transform_view}% \tcode{adjacent_transform_view} takes an invocable object and a view and produces a view whose $M^\text{th}$ element is the result of applying the invocable object @@ -12875,7 +13174,8 @@ a constant expression \tcode{N}: \begin{itemize} \item -If \tcode{N} is equal to \tcode{0}, +If \tcode{N} is equal to \tcode{0} and +\tcode{decltype((E))} models \libconcept{forward_range}, \tcode{views::adjacent_transform(E, F)} is expression-equivalent to \tcode{((void)E, views::zip_transform(F))}, except that the evaluations of \tcode{E} and \tcode{F} are @@ -12900,9 +13200,12 @@ \rSec3[range.adjacent.transform.view]{Class template \tcode{adjacent_transform_view}} +\indexlibraryglobal{adjacent_transform_view}% +\indexlibrarymember{base}{adjacent_transform_view}% \indexlibrarymember{begin}{adjacent_transform_view}% \indexlibrarymember{end}{adjacent_transform_view}% \indexlibrarymember{size}{adjacent_transform_view}% +\indexlibrarymember{reserve_hint}{adjacent_transform_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> @@ -12967,10 +13270,19 @@ constexpr auto size() const requires @\libconcept{sized_range}@ { return @\exposid{inner_}@.size(); } + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@<@\exposid{InnerView}@> { + return @\exposid{inner_}@.reserve_hint(); + } + + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@ { + return @\exposid{inner_}@.reserve_hint(); + } }; } \end{codeblock} +\indexlibraryctor{adjacent_transform_view}% \begin{itemdecl} constexpr explicit adjacent_transform_view(V base, F fun); \end{itemdecl} @@ -12984,6 +13296,7 @@ \rSec3[range.adjacent.transform.iterator]{Class template \tcode{adjacent_transform_view::\exposid{iterator}}} +\indexlibraryglobal{adjacent_transform_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> @@ -13078,6 +13391,7 @@ \end{itemize} \end{itemize} +\indexlibraryctor{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, @\exposid{inner-iterator}@ inner); \end{itemdecl} @@ -13089,6 +13403,7 @@ \exposid{inner_} with \tcode{std::move(inner)}. \end{itemdescr} +\indexlibraryctor{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@<@\exposid{inner-iterator}@, @\exposid{inner-iterator}@>; @@ -13101,6 +13416,7 @@ \exposid{inner_} with \tcode{std::move(i.\exposid{inner_})}. \end{itemdescr} +\indexlibrarymember{operator*}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr decltype(auto) operator*() const noexcept(@\seebelow@); \end{itemdecl} @@ -13117,13 +13433,14 @@ \pnum \remarks -Let \tcode{Is} be the pack \tcode{0, 1, \ldots, (N-1)}. +Let \tcode{Is} be the pack \tcode{0, 1, \ldots, (N - 1)}. The exception specification is equivalent to: \begin{codeblock} noexcept(invoke(*@\exposid{parent_}@->@\exposid{fun_}@, *std::get(@\exposid{inner_}@.@\exposid{current_}@)...)) \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -13138,6 +13455,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -13153,6 +13471,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -13167,6 +13486,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -13182,6 +13502,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -13196,6 +13517,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-=}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -13210,6 +13532,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator[]}{adjacent_transform_view::\exposid{iterator}}% \begin{itemdecl} constexpr decltype(auto) operator[](difference_type n) const requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -13286,6 +13609,7 @@ \rSec3[range.adjacent.transform.sentinel]{Class template \tcode{adjacent_transform_view::\exposid{sentinel}}} +\indexlibraryglobal{adjacent_transform_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{move_constructible}@ F, size_t N> @@ -13319,6 +13643,7 @@ } \end{codeblock} +\indexlibraryctor{adjacent_transform_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(@\exposid{inner-sentinel}@ inner); \end{itemdecl} @@ -13329,6 +13654,7 @@ Initializes \exposid{inner_} with \tcode{inner}. \end{itemdescr} +\indexlibraryctor{adjacent_transform_view::\exposid{sentinel}}% \begin{itemdecl} constexpr @\exposid{sentinel}@(@\exposid{sentinel}@ i) requires Const && @\libconcept{convertible_to}@<@\exposid{inner-sentinel}@, @\exposid{inner-sentinel}@>; @@ -13408,9 +13734,7 @@ \rSec3[range.chunk.view.input]{Class template \tcode{chunk_view} for input ranges} -\indexlibrarymember{begin}{chunk_view}% -\indexlibrarymember{end}{chunk_view}% -\indexlibrarymember{size}{chunk_view}% +\indexlibraryglobal{chunk_view}% \begin{codeblock} namespace std::ranges { template @@ -13447,6 +13771,9 @@ constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; }; template @@ -13454,6 +13781,7 @@ } \end{codeblock} +\indexlibraryctor{chunk_view}% \begin{itemdecl} constexpr explicit chunk_view(V base, range_difference_t n); \end{itemdecl} @@ -13469,6 +13797,7 @@ \exposid{n_} with \tcode{n}. \end{itemdescr} +\indexlibrarymember{begin}{chunk_view}% \begin{itemdecl} constexpr @\exposid{outer-iterator}@ begin(); \end{itemdecl} @@ -13484,6 +13813,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{end}{chunk_view}% \begin{itemdecl} constexpr default_sentinel_t end() const noexcept; \end{itemdecl} @@ -13494,6 +13824,7 @@ \tcode{default_sentinel}. \end{itemdescr} +\indexlibrarymember{size}{chunk_view}% \begin{itemdecl} constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; @@ -13508,9 +13839,25 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{reserve_hint}{chunk_view}% +\begin{itemdecl} +constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; +constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto s = static_cast>(ranges::reserve_hint(@\exposidnc{base_}@)); +return @\exposidnc{to-unsigned-like}@(@\exposidnc{div-ceil}@(s, @\exposidnc{n_}@)); +\end{codeblock} +\end{itemdescr} + \rSec3[range.chunk.outer.iter]{Class \tcode{chunk_view::\exposid{outer-iterator}}} -\indexlibraryglobal{chunk_view::outer-iterator}% +\indexlibraryglobal{chunk_view::\exposid{outer-iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -13544,6 +13891,7 @@ } \end{codeblock} +\indexlibraryctor{chunk_view::\exposid{outer-iterator}}% \begin{itemdecl} constexpr explicit @\exposid{outer-iterator}@(chunk_view& parent); \end{itemdecl} @@ -13554,6 +13902,7 @@ Initializes \exposid{parent_} with \tcode{addressof(parent)}. \end{itemdescr} +\indexlibrarymember{operator*}{chunk_view::\exposid{outer-iterator}}% \begin{itemdecl} constexpr value_type operator*() const; \end{itemdecl} @@ -13568,6 +13917,7 @@ \tcode{value_type(*\exposid{parent_})}. \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{outer-iterator}}% \begin{itemdecl} constexpr @\exposid{outer-iterator}@& operator++(); \end{itemdecl} @@ -13587,6 +13937,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{outer-iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -13641,7 +13992,7 @@ \rSec3[range.chunk.outer.value]{Class \tcode{chunk_view::\exposid{outer-iterator}::value_type}} -\indexlibraryglobal{chunk_view::outer-iterator::value_type}% +\indexlibraryglobal{chunk_view::\exposid{outer-iterator}::value_type}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -13662,6 +14013,7 @@ } \end{codeblock} +\indexlibraryctor{chunk_view::\exposid{outer-iterator}::value_type}% \begin{itemdecl} constexpr explicit value_type(chunk_view& parent); \end{itemdecl} @@ -13672,6 +14024,7 @@ Initializes \exposid{parent_} with \tcode{addressof(parent)}. \end{itemdescr} +\indexlibrarymember{begin}{chunk_view::\exposid{outer-iterator}::value_type}% \begin{itemdecl} constexpr @\exposid{inner-iterator}@ begin() const noexcept; \end{itemdecl} @@ -13682,6 +14035,7 @@ \tcode{\exposid{inner-iterator}(*\exposid{parent_})}. \end{itemdescr} +\indexlibrarymember{end}{chunk_view::\exposid{outer-iterator}::value_type}% \begin{itemdecl} constexpr default_sentinel_t end() const noexcept; \end{itemdecl} @@ -13692,6 +14046,7 @@ \tcode{default_sentinel}. \end{itemdescr} +\indexlibrarymember{size}{chunk_view::\exposid{outer-iterator}::value_type}% \begin{itemdecl} constexpr auto size() const requires @\libconcept{sized_sentinel_for}@, iterator_t>; @@ -13709,7 +14064,7 @@ \rSec3[range.chunk.inner.iter]{Class \tcode{chunk_view::\exposid{inner-iterator}}} -\indexlibraryglobal{chunk_view::inner-iterator}% +\indexlibraryglobal{chunk_view::\exposid{inner-iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -13750,6 +14105,7 @@ } \end{codeblock} +\indexlibraryctor{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} constexpr explicit @\exposid{inner-iterator}@(chunk_view& parent) noexcept; \end{itemdecl} @@ -13760,6 +14116,7 @@ Initializes \exposid{parent_} with \tcode{addressof(parent)}. \end{itemdescr} +\indexlibrarymember{base}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} constexpr const iterator_t& base() const &; \end{itemdecl} @@ -13770,6 +14127,7 @@ Equivalent to: \tcode{return *\exposid{parent_}->\exposid{current_};} \end{itemdescr} +\indexlibrarymember{operator*}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} constexpr range_reference_t operator*() const; \end{itemdecl} @@ -13784,6 +14142,7 @@ Equivalent to: \tcode{return **\exposid{parent_}->\exposid{current_};} \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} constexpr @\exposid{inner-iterator}@& operator++(); \end{itemdecl} @@ -13806,6 +14165,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -13816,6 +14176,7 @@ Equivalent to \tcode{++*this}. \end{itemdescr} +\indexlibrarymember{operator==}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{inner-iterator}@& x, default_sentinel_t); \end{itemdecl} @@ -13826,6 +14187,7 @@ \tcode{x.\exposid{parent_}->\exposid{remainder_} == 0}. \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(default_sentinel_t y, const @\exposid{inner-iterator}@& x) requires @\libconcept{sized_sentinel_for}@, iterator_t>; @@ -13841,6 +14203,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{inner-iterator}@& x, default_sentinel_t y) requires @\libconcept{sized_sentinel_for}@, iterator_t>; @@ -13852,6 +14215,7 @@ Equivalent to: \tcode{return -(y - x);} \end{itemdescr} +\indexlibrarymember{iter_move}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} friend constexpr range_rvalue_reference_t iter_move(const @\exposid{inner-iterator}@& i) noexcept(noexcept(ranges::iter_move(*i.@\exposid{parent_}@->@\exposid{current_}@))); @@ -13863,6 +14227,7 @@ Equivalent to: \tcode{return ranges::iter_move(*i.\exposid{parent_}->\exposid{current_});} \end{itemdescr} +\indexlibrarymember{iter_swap}{chunk_view::\exposid{inner-iterator}}% \begin{itemdecl} friend constexpr void iter_swap(const @\exposid{inner-iterator}@& x, const @\exposid{inner-iterator}@& y) noexcept(noexcept(ranges::iter_swap(*x.@\exposid{parent_}@->@\exposid{current_}@, *y.@\exposid{parent_}@->@\exposid{current_}@))) @@ -13877,9 +14242,9 @@ \rSec3[range.chunk.view.fwd]{Class template \tcode{chunk_view} for forward ranges} +\indexlibraryglobal{chunk_view}% \indexlibrarymember{begin}{chunk_view}% \indexlibrarymember{end}{chunk_view}% -\indexlibrarymember{size}{chunk_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -13929,10 +14294,14 @@ constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; }; } \end{codeblock} +\indexlibraryctor{chunk_view}% \begin{itemdecl} constexpr explicit chunk_view(V base, range_difference_t n); \end{itemdecl} @@ -13948,6 +14317,7 @@ \exposid{n_} with \tcode{n}. \end{itemdescr} +\indexlibrarymember{size}{chunk_view}% \begin{itemdecl} constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; @@ -13962,8 +14332,25 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{reserve_hint}{chunk_view}% +\begin{itemdecl} +constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; +constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto s = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); +return @\exposid{to-unsigned-like}@(@\exposid{div-ceil}@(s, @\exposid{n_}@)); +\end{codeblock} +\end{itemdescr} + \rSec3[range.chunk.fwd.iter]{Class template \tcode{chunk_view::\exposid{iterator}} for forward ranges} +\indexlibraryglobal{chunk_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{view}@ V> @@ -14054,6 +14441,7 @@ Otherwise, \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. \end{itemize} +\indexlibraryctor{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{Parent}@* parent, iterator_t<@\exposid{Base}@> current, range_difference_t<@\exposid{Base}@> missing = 0); @@ -14068,6 +14456,7 @@ \exposid{missing_} with \tcode{missing}. \end{itemdescr} +\indexlibraryctor{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>> @@ -14083,6 +14472,7 @@ \exposid{missing_} with \tcode{i.\exposid{missing_}}. \end{itemdescr} +\indexlibrarymember{base}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr iterator_t<@\exposid{Base}@> base() const; \end{itemdecl} @@ -14093,6 +14483,7 @@ \exposid{current_}. \end{itemdescr} +\indexlibrarymember{operator*}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr value_type operator*() const; \end{itemdecl} @@ -14107,6 +14498,7 @@ \tcode{views::take(subrange(\exposid{current_}, \exposid{end_}), \exposid{n_})}. \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -14125,6 +14517,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -14140,6 +14533,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -14155,6 +14549,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -14170,6 +14565,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14200,6 +14596,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-=}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14211,6 +14608,7 @@ Equivalent to: \tcode{return *this += -x;} \end{itemdescr} +\indexlibrarymember{operator[]}{chunk_view::\exposid{iterator}}% \begin{itemdecl} constexpr value_type operator[](difference_type n) const requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14222,6 +14620,7 @@ \tcode{*(*this + n)}. \end{itemdescr} +\indexlibrarymember{operator-=}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); \end{itemdecl} @@ -14232,6 +14631,7 @@ \tcode{x.\exposid{current_} == y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator==}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); \end{itemdecl} @@ -14242,6 +14642,7 @@ \tcode{x.\exposid{current_} == x.\exposid{end_}}. \end{itemdescr} +\indexlibrarymember{operator<}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14253,6 +14654,7 @@ \tcode{x.\exposid{current_} < y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator>}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14264,6 +14666,7 @@ Equivalent to: \tcode{return y < x;} \end{itemdescr} +\indexlibrarymember{operator<=}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14275,6 +14678,7 @@ Equivalent to: \tcode{return !(y < x);} \end{itemdescr} +\indexlibrarymember{operator>=}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14286,6 +14690,7 @@ Equivalent to: \tcode{return !(x < y);} \end{itemdescr} +\indexlibrarymember{operator<=>}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @@ -14298,6 +14703,7 @@ \tcode{x.\exposid{current_} <=> y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator+}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14316,6 +14722,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14332,6 +14739,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; @@ -14343,6 +14751,7 @@ \tcode{(x.\exposid{current_} - y.\exposid{current_} + x.\exposid{missing_} - y.\exposid{missing_}) / x.\exposid{n_}}. \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(default_sentinel_t y, const @\exposid{iterator}@& x) requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; @@ -14354,6 +14763,7 @@ \tcode{\exposid{div-ceil}(x.\exposid{end_} - x.\exposid{current_}, x.\exposid{n_})}. \end{itemdescr} +\indexlibrarymember{operator-}{chunk_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{iterator}@& x, default_sentinel_t y) requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; @@ -14398,9 +14808,8 @@ \rSec3[range.slide.view]{Class template \tcode{slide_view}} -\indexlibrarymember{begin}{slide_view}% -\indexlibrarymember{end}{slide_view}% -\indexlibrarymember{size}{slide_view}% +\indexlibraryglobal{slide_view}% +\indexlibraryctor{slide_view}% \begin{codeblock} namespace std::ranges { template @@ -14442,6 +14851,9 @@ constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; + + constexpr auto reserve_hintsize() requires @\libconcept{approximately_sized_range}@; + constexpr auto reserve_hintsize() const requires @\libconcept{approximately_sized_range}@; }; template @@ -14449,6 +14861,7 @@ } \end{codeblock} +\indexlibraryctor{slide_view}% \begin{itemdecl} constexpr explicit slide_view(V base, range_difference_t n); \end{itemdecl} @@ -14464,6 +14877,7 @@ \exposid{n_} with \tcode{n}. \end{itemdescr} +\indexlibrarymember{begin}{slide_view}% \begin{itemdecl} constexpr auto begin() requires (!(@\exposconcept{simple-view}@ && @\exposconcept{slide-caches-nothing}@)); @@ -14492,6 +14906,7 @@ when \tcode{V} models \exposconcept{slide-caches-first}. \end{itemdescr} +\indexlibrarymember{begin}{slide_view}% \begin{itemdecl} constexpr auto begin() const requires @\exposconcept{slide-caches-nothing}@; \end{itemdecl} @@ -14502,6 +14917,7 @@ \tcode{\exposid{iterator}(ranges::begin(\exposid{base_}), \exposid{n_})}. \end{itemdescr} +\indexlibrarymember{end}{slide_view}% \begin{itemdecl} constexpr auto end() requires (!(@\exposconcept{simple-view}@ && @\exposconcept{slide-caches-nothing}@)); @@ -14539,6 +14955,7 @@ when \tcode{V} models \exposconcept{slide-caches-last}. \end{itemdescr} +\indexlibrarymember{end}{slide_view}% \begin{itemdecl} constexpr auto end() const requires @\exposconcept{slide-caches-nothing}@; \end{itemdecl} @@ -14549,6 +14966,7 @@ \tcode{begin() + range_difference_t(size())}. \end{itemdescr} +\indexlibrarymember{size}{slide_view}% \begin{itemdecl} constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; @@ -14565,8 +14983,27 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{reserve_hint}{slide_view}% +\begin{itemdecl} +constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; +constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto sz = static_cast>(ranges::reserve_hint(@\exposid{base_}@)) - + @\exposid{n_}@ + 1; +if (sz < 0) sz = 0; +return @\exposid{to-unsigned-like}@(sz); +\end{codeblock} +\end{itemdescr} + \rSec3[range.slide.iterator]{Class template \tcode{slide_view::\exposid{iterator}}} +\indexlibraryglobal{slide_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V> @@ -14654,6 +15091,7 @@ If the invocation of any non-const member function of \exposid{iterator} exits via an exception, the \exposid{iterator} acquires a singular value. +\indexlibraryctor{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current, range_difference_t<@\exposid{Base}@> n) requires (!@\exposconcept{slide-caches-first}@<@\exposid{Base}@>); @@ -14666,6 +15104,7 @@ \exposid{n_} with \tcode{n}. \end{itemdescr} +\indexlibraryctor{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current, iterator_t<@\exposid{Base}@> last_ele, range_difference_t<@\exposid{Base}@> n) @@ -14680,6 +15119,7 @@ \exposid{n_} with \tcode{n}. \end{itemdescr} +\indexlibraryctor{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; @@ -14697,6 +15137,7 @@ \end{note} \end{itemdescr} +\indexlibrarymember{operator*}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator*() const; \end{itemdecl} @@ -14707,6 +15148,7 @@ \tcode{views::counted(\exposid{current_}, \exposid{n_})}. \end{itemdescr} +\indexlibrarymember{operator++}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -14727,6 +15169,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator++}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -14742,6 +15185,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -14762,6 +15206,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator--}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@<@\exposid{Base}@>; \end{itemdecl} @@ -14777,6 +15222,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14799,6 +15245,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator-=}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14821,6 +15268,7 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{operator[]}{slide_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator[](difference_type n) const requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14832,6 +15280,7 @@ Equivalent to: \tcode{return views::counted(\exposid{current_} + n, \exposid{n_});} \end{itemdescr} +\indexlibrarymember{operator==}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); \end{itemdecl} @@ -14844,6 +15293,7 @@ otherwise, \tcode{x.\exposid{current_} == y.\exposid{cur\-rent_}}. \end{itemdescr} +\indexlibrarymember{operator<}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator<(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14855,6 +15305,7 @@ \tcode{x.\exposid{current_} < y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator>}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14866,6 +15317,7 @@ Equivalent to: \tcode{return y < x;} \end{itemdescr} +\indexlibrarymember{operator<=}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator<=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14877,6 +15329,7 @@ Equivalent to: \tcode{return !(y < x);} \end{itemdescr} +\indexlibrarymember{operator>=}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator>=(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14888,6 +15341,7 @@ Equivalent to: \tcode{return !(x < y);} \end{itemdescr} +\indexlibrarymember{operator<=>}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{random_access_range}@<@\exposid{Base}@> && @@ -14900,6 +15354,7 @@ \tcode{x.\exposid{current_} <=> y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator+}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14918,6 +15373,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& i, difference_type n) requires @\libconcept{random_access_range}@<@\exposid{Base}@>; @@ -14934,6 +15390,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator-}{slide_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; @@ -14949,6 +15406,7 @@ \rSec3[range.slide.sentinel]{Class \tcode{slide_view::\exposid{sentinel}}} +\indexlibraryglobal{slide_view::\exposid{sentinel}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V> @@ -14979,6 +15437,7 @@ only when \tcode{\exposconcept{slide-caches-first}} is \tcode{true}. \end{note} +\indexlibraryctor{slide_view::\exposid{sentinel}}% \begin{itemdecl} constexpr explicit @\exposid{sentinel}@(sentinel_t end); \end{itemdecl} @@ -14989,6 +15448,7 @@ Initializes \exposid{end_} with \tcode{end}. \end{itemdescr} +\indexlibrarymember{operator==}{slide_view::\exposid{sentinel}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); \end{itemdecl} @@ -14999,6 +15459,7 @@ \tcode{x.\exposid{last_ele_} == y.\exposid{end_}}. \end{itemdescr} +\indexlibrarymember{operator-}{slide_view::\exposid{sentinel}}% \begin{itemdecl} friend constexpr range_difference_t operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) @@ -15011,6 +15472,7 @@ \tcode{x.\exposid{last_ele_} - y.\exposid{end_}}. \end{itemdescr} +\indexlibrarymember{operator-}{slide_view::\exposid{sentinel}}% \begin{itemdecl} friend constexpr range_difference_t operator-(const @\exposid{sentinel}@& y, const @\exposid{iterator}@& x) @@ -15059,6 +15521,7 @@ \rSec3[range.chunk.by.view]{Class template \tcode{chunk_by_view}} +\indexlibraryglobal{chunk_by_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> @@ -15092,6 +15555,7 @@ } \end{codeblock} +\indexlibraryctor{chunk_by_view}% \begin{itemdecl} constexpr explicit chunk_by_view(V base, Pred pred); \end{itemdecl} @@ -15114,6 +15578,7 @@ Equivalent to: \tcode{return *\exposid{pred_};} \end{itemdescr} +\indexlibrarymember{begin}{chunk_by_view}% \begin{itemdecl} constexpr @\exposid{iterator}@ begin(); \end{itemdecl} @@ -15135,6 +15600,7 @@ for use on subsequent calls. \end{itemdescr} +\indexlibrarymember{end}{chunk_by_view}% \begin{itemdecl} constexpr auto end(); \end{itemdecl} @@ -15199,6 +15665,7 @@ \rSec3[range.chunk.by.iter]{Class \tcode{chunk_by_view::\exposid{iterator}}} +\indexlibraryglobal{chunk_by_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{forward_range}@ V, @\libconcept{indirect_binary_predicate}@, iterator_t> Pred> @@ -15242,6 +15709,7 @@ Otherwise, \tcode{iterator_concept} denotes \tcode{forward_iterator_tag}. \end{itemize} +\indexlibraryctor{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(chunk_by_view& parent, iterator_t current, iterator_t next); \end{itemdecl} @@ -15254,6 +15722,7 @@ \exposid{next_} with \tcode{next}. \end{itemdescr} +\indexlibrarymember{operator*}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr value_type operator*() const; \end{itemdecl} @@ -15268,6 +15737,7 @@ \tcode{subrange(\exposid{current_}, \exposid{next_})}. \end{itemdescr} +\indexlibrarymember{operator++}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -15287,6 +15757,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int); \end{itemdecl} @@ -15302,6 +15773,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\libconcept{bidirectional_range}@; \end{itemdecl} @@ -15317,6 +15789,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\libconcept{bidirectional_range}@; \end{itemdecl} @@ -15332,6 +15805,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator==}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y); \end{itemdecl} @@ -15342,6 +15816,7 @@ \tcode{x.\exposid{current_} == y.\exposid{current_}}. \end{itemdescr} +\indexlibrarymember{operator==}{chunk_by_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); \end{itemdecl} @@ -15379,6 +15854,7 @@ \rSec3[range.stride.view]{Class template \tcode{stride_view}} +\indexlibraryglobal{stride_view}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V> @@ -15428,6 +15904,9 @@ constexpr auto size() requires @\libconcept{sized_range}@; constexpr auto size() const requires @\libconcept{sized_range}@; + + constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; + constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; }; template @@ -15477,8 +15956,25 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{reserve_hint}{stride_view}% +\begin{itemdecl} +constexpr auto reserve_hint() requires @\libconcept{approximately_sized_range}@; +constexpr auto reserve_hint() const requires @\libconcept{approximately_sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto s = static_cast>(ranges::reserve_hint(@\exposid{base_}@)); +return @\exposid{to-unsigned-like}@(@\exposid{div-ceil}@(s, @\exposid{stride_}@)); +\end{codeblock} +\end{itemdescr} + \rSec3[range.stride.iterator]{Class template \tcode{stride_view::\exposid{iterator}}} +\indexlibraryglobal{stride_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ V> @@ -15683,7 +16179,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{++*this;} +Equivalent to \tcode{++*this;} \end{itemdescr} \indexlibrarymember{operator++}{stride_view::\exposid{iterator}}% @@ -15790,7 +16286,7 @@ \indexlibrarymember{operator==}{stride_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) - requires @\libconcept{equality_comparable}@>; + requires @\libconcept{equality_comparable}@>; \end{itemdecl} \begin{itemdescr} @@ -16009,6 +16505,7 @@ \rSec3[range.cartesian.view]{Class template \tcode{cartesian_product_view}} +\indexlibraryglobal{cartesian_product_view}% \begin{codeblock} namespace std::ranges { template @@ -16087,6 +16584,7 @@ } \end{codeblock} +\indexlibraryctor{cartesian_product_view}% \begin{itemdecl} constexpr explicit cartesian_product_view(First first_base, Vs... bases); \end{itemdecl} @@ -16098,6 +16596,7 @@ with \tcode{std::move(first_base), std::move(bases)...}. \end{itemdescr} +\indexlibrarymember{begin}{cartesian_product_view}% \begin{itemdecl} constexpr @\exposid{iterator}@ begin() requires (!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@); @@ -16112,6 +16611,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{begin}{cartesian_product_view}% \begin{itemdecl} constexpr @\exposid{iterator}@ begin() const requires (@\libconcept{range}@ && ... && @\libconcept{range}@); @@ -16126,6 +16626,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{end}{cartesian_product_view}% \begin{itemdecl} constexpr @\exposid{iterator}@ end() requires ((!@\exposconcept{simple-view}@ || ... || !@\exposconcept{simple-view}@) @@ -16163,6 +16664,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{end}{cartesian_product_view}% \begin{itemdecl} constexpr default_sentinel_t end() const noexcept; \end{itemdecl} @@ -16173,6 +16675,7 @@ \tcode{default_sentinel}. \end{itemdescr} +\indexlibrarymember{size}{cartesian_product_view}% \begin{itemdecl} constexpr @\seebelow@ size() requires @\exposconcept{cartesian-product-is-sized}@; @@ -16204,6 +16707,7 @@ \rSec3[range.cartesian.iterator]{Class template \tcode{cartesian_product_view::\exposid{iterator}}} +\indexlibraryglobal{cartesian_product_view::\exposid{iterator}}% \begin{codeblock} namespace std::ranges { template<@\libconcept{input_range}@ First, @\libconcept{forward_range}@... Vs> @@ -16325,7 +16829,6 @@ the product of the maximum sizes of all underlying ranges if such a type exists. -\pnum \begin{itemdecl} template constexpr void @\exposid{next}@(); @@ -16399,6 +16902,7 @@ \exposid{scaled-sum}. \end{itemdescr} +\indexlibraryctor{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, tuple>, iterator_t<@\exposid{maybe-const}@>...> current); @@ -16412,6 +16916,7 @@ \exposid{current_} with \tcode{std::move(current)}. \end{itemdescr} +\indexlibraryctor{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) requires Const && (@\libconcept{convertible_to}@, iterator_t> && @@ -16426,6 +16931,7 @@ \exposid{current_} with \tcode{std::move(i.\exposid{current_})}. \end{itemdescr} +\indexlibrarymember{operator*}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr auto operator*() const; \end{itemdecl} @@ -16439,6 +16945,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator++(); \end{itemdecl} @@ -16453,6 +16960,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator++}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr void operator++(int); \end{itemdecl} @@ -16463,6 +16971,7 @@ Equivalent to \tcode{++*this}. \end{itemdescr} +\indexlibrarymember{operator++}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator++(int) requires @\libconcept{forward_range}@<@\exposid{maybe-const}@>; \end{itemdecl} @@ -16478,6 +16987,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator--() requires @\exposconcept{cartesian-product-is-bidirectional}@; @@ -16493,6 +17003,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator--}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@ operator--(int) requires @\exposconcept{cartesian-product-is-bidirectional}@; @@ -16509,6 +17020,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator+=}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator+=(difference_type x) requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16549,6 +17061,7 @@ Constant. \end{itemdescr} +\indexlibrarymember{operator-=}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr @\exposid{iterator}@& operator-=(difference_type x) requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16564,6 +17077,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{operator[]}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} constexpr reference operator[](difference_type n) const requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16575,6 +17089,7 @@ Equivalent to: \tcode{return *((*this) + n);} \end{itemdescr} +\indexlibrarymember{operator==}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\libconcept{equality_comparable}@>>; @@ -16586,6 +17101,7 @@ Equivalent to: \tcode{return x.\exposid{current_} == y.\exposid{current_};} \end{itemdescr} +\indexlibrarymember{operator==}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr bool operator==(const @\exposid{iterator}@& x, default_sentinel_t); \end{itemdecl} @@ -16599,6 +17115,7 @@ otherwise, \tcode{false}. \end{itemdescr} +\indexlibrarymember{operator<=>}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr auto operator<=>(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\exposconcept{all-random-access}@; @@ -16610,6 +17127,7 @@ Equivalent to: \tcode{return x.\exposid{current_} <=> y.\exposid{current_};} \end{itemdescr} +\indexlibrarymember{operator+}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator+(const @\exposid{iterator}@& x, difference_type y) requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16621,6 +17139,7 @@ Equivalent to: \tcode{return \exposid{iterator}(x) += y;} \end{itemdescr} +\indexlibrarymember{operator+}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator+(difference_type x, const @\exposid{iterator}@& y) requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16632,6 +17151,7 @@ Equivalent to: \tcode{return y + x;} \end{itemdescr} +\indexlibrarymember{operator-}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr @\exposid{iterator}@ operator-(const @\exposid{iterator}@& x, difference_type y) requires @\exposconcept{cartesian-product-is-random-access}@; @@ -16643,6 +17163,7 @@ Equivalent to: \tcode{return \exposid{iterator}(x) -= y;} \end{itemdescr} +\indexlibrarymember{operator-}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\exposconcept{cartesian-is-sized-sentinel}@; @@ -16654,6 +17175,7 @@ Equivalent to: \tcode{return x.\exposid{distance-from}(y.\exposid{current_});} \end{itemdescr} +\indexlibrarymember{operator-}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(const @\exposid{iterator}@& i, default_sentinel_t) requires @\exposconcept{cartesian-is-sized-sentinel}@; @@ -16678,6 +17200,7 @@ Equivalent to: \tcode{return i.\exposid{distance-from}(\exposid{end-tuple});} \end{itemdescr} +\indexlibrarymember{operator-}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr difference_type operator-(default_sentinel_t s, const @\exposid{iterator}@& i) requires @\exposconcept{cartesian-is-sized-sentinel}@; @@ -16689,6 +17212,7 @@ Equivalent to: \tcode{return -(i - s);} \end{itemdescr} +\indexlibrarymember{iter_move}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr auto iter_move(const @\exposid{iterator}@& i) noexcept(@\seebelow@); \end{itemdecl} @@ -16712,6 +17236,7 @@ \end{itemize} \end{itemdescr} +\indexlibrarymember{iter_swap}{cartesian_product_view::\exposid{iterator}}% \begin{itemdecl} friend constexpr void iter_swap(const @\exposid{iterator}@& l, const @\exposid{iterator}@& r) noexcept(@\seebelow@) requires (@\libconcept{indirectly_swappable}@>> && ... && @@ -16736,72 +17261,702 @@ \end{itemize} \end{itemdescr} -\rSec1[coro.generator]{Range generators} +\rSec2[range.cache.latest]{Cache latest view} -\rSec2[coroutine.generator.overview]{Overview} +\rSec3[range.cache.latest.overview]{Overview} \pnum -Class template \tcode{generator} presents -a view of the elements yielded by the evaluation of a coroutine. +\tcode{cache_latest_view} caches the last-accessed element of +its underlying sequence +so that the element does not have to be recomputed on repeated access. +\begin{note} +This is useful if computation of the element to produce is expensive. +\end{note} \pnum -A \tcode{generator} generates a sequence of elements by -repeatedly resuming the coroutine from which it was returned. -Elements of the sequence are produced by the coroutine -each time a \tcode{co_yield} statement is evaluated. -When the \tcode{co_yield} statement is of the form -\tcode{co_yield elements_of(r)}, -each element of the range \tcode{r} -is successively produced as an element of the sequence. -\begin{example} -\begin{codeblock} -generator ints(int start = 0) { - while (true) - co_yield start++; -} - -void f() { - for (auto i : ints() | views::take(3)) - cout << i << ' '; // prints \tcode{0 1 2} -} -\end{codeblock} -\end{example} +The name \tcode{views::cache_latest} denotes +a range adaptor object\iref{range.adaptor.object}. +Let \tcode{E} be an expression. +The expression \tcode{views::cache_latest(E)} is expression-equivalent to +\tcode{cache_latest_view(E)}. -\rSec2[generator.syn]{Header \tcode{} synopsis} +\rSec3[range.cache.latest.view]{Class template \tcode{cache_latest_view}} -\indexheader{generator}% \begin{codeblock} -namespace std { - // \ref{coro.generator.class}, class template \tcode{generator} - template - class generator; - - namespace pmr { - template - using generator = std::generator>; - } -} -\end{codeblock} - -\rSec2[coro.generator.class]{Class template \tcode{generator}} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class @\libglobal{cache_latest_view}@ : public view_interface> { + V @\exposid{base_}@ = V(); // \expos + using @\exposid{cache-t}@ = conditional_t>, // \expos + add_pointer_t>, + range_reference_t>; -\begin{codeblock} -namespace std { - template - class @\libglobal{generator}@ : public ranges::view_interface> { - private: - using @\exposid{value}@ = conditional_t, remove_cvref_t, V>; // \expos - using @\exposid{reference}@ = conditional_t, Ref&&, Ref>; // \expos + @\exposid{non-propagating-cache}@<@\exposid{cache-t}@> @\exposid{cache_}@; // \expos - // \ref{coro.generator.iterator}, class \tcode{generator::\exposid{iterator}} - class @\exposidnc{iterator}@; // \expos + // \ref{range.cache.latest.iterator}, class \tcode{cache_latest_view::\exposid{iterator}} + class @\exposid{iterator}@; // \expos + // \ref{range.cache.latest.sentinel}, class \tcode{cache_latest_view::\exposid{sentinel}} + class @\exposid{sentinel}@; // \expos public: - using yielded = - conditional_t, @\exposid{reference}@, const @\exposid{reference}@&>; - - // \ref{coro.generator.promise}, class \tcode{generator::promise_type} - class promise_type; + cache_latest_view() requires @\libconcept{default_initializable}@ = default; + constexpr explicit cache_latest_view(V base); + + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + + constexpr auto begin(); + constexpr auto end(); + + constexpr auto size() requires @\libconcept{sized_range}@; + constexpr auto size() const requires @\libconcept{sized_range}@; + }; + + template + cache_latest_view(R&&) -> cache_latest_view>; +} +\end{codeblock} + +\indexlibraryctor{cache_latest_view}% +\begin{itemdecl} +constexpr explicit cache_latest_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{base_} with \tcode{std::move(base)}. +\end{itemdescr} + +\indexlibrarymember{begin}{cache_latest_view}% +\begin{itemdecl} +constexpr auto begin(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(*this);} +\end{itemdescr} + +\indexlibrarymember{end}{cache_latest_view}% +\begin{itemdecl} +constexpr auto end(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{sentinel}(*this);} +\end{itemdescr} + +\indexlibrarymember{size}{cache_latest_view}% +\begin{itemdecl} +constexpr auto size() requires @\libconcept{sized_range}@; +constexpr auto size() const requires @\libconcept{sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::size(\exposid{base_});} +\end{itemdescr} + +\rSec3[range.cache.latest.iterator]{Class \tcode{cache_latest_view::\exposid{iterator}}} + +\indexlibraryglobal{cache_latest_view::\exposid{iiterator}}% +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class cache_latest_view::@\exposid{iterator}@ { + cache_latest_view* @\exposid{parent_}@; // \expos + iterator_t @\exposid{current_}@; // \expos + + constexpr explicit @\exposid{iterator}@(cache_latest_view& parent); // \expos + + public: + using difference_type = range_difference_t; + using value_type = range_value_t; + using iterator_concept = input_iterator_tag; + + @\exposid{iterator}@(@\exposid{iterator}@&&) = default; + @\exposid{iterator}@& operator=(@\exposid{iterator}@&&) = default; + + constexpr iterator_t base() &&; + constexpr const iterator_t& base() const & noexcept; + + constexpr range_reference_t& operator*() const; + + constexpr @\exposid{iterator}@& operator++(); + constexpr void operator++(int); + + friend constexpr range_rvalue_reference_t iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); + + friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; + }; +} +\end{codeblock} + +\indexlibraryctor{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(cache_latest_view& parent); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with +\tcode{ranges::begin(parent.\exposid{base_})} +and \exposid{parent_} with \tcode{addressof(par\-ent)}. +\end{itemdescr} + +\indexlibrarymember{base}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr iterator_t base() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::move(\exposid{current_})}. +\end{itemdescr} + +\indexlibrarymember{base}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr const iterator_t& base() const & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{current_}. +\end{itemdescr} + +\indexlibrarymember{operator++}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{parent_}@->@\exposid{cache_}@.reset(); +++@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator++}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{++*this}. +\end{itemdescr} + +\indexlibrarymember{operator*}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +constexpr range_reference_t& operator*() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if constexpr (is_reference_v>) { + if (!@\exposid{parent_}@->@\exposid{cache_}@) { + @\exposid{parent_}@->@\exposid{cache_}@ = addressof(@\exposid{as-lvalue}@(*@\exposid{current_}@)); + } + return **@\exposid{parent_}@->@\exposid{cache_}@; +} else { + if (!@\exposid{parent_}@->c@\exposid{ache_}@) { + @\exposid{parent_}@->@\exposid{cache_}@.@\exposid{emplace-deref}@(@\exposid{current_}@); + } + return *@\exposid{parent_}@->@\exposid{cache_}@; +} +\end{codeblock} +\begin{note} +Evaluations of \tcode{operator*} on the same iterator object +can conflict\iref{intro.races}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{iter_move}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr range_rvalue_reference_t iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::iter_move(i.\exposid{current_});} +\end{itemdescr} + +\indexlibrarymember{iter_swap}{cache_latest_view::\exposid{iterator}}% +\begin{itemdecl} +friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to +\tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_})}. +\end{itemdescr} + +\rSec3[range.cache.latest.sentinel]{Class \tcode{cache_latest_view::\exposid{sentinel}}} + +\indexlibraryglobal{cache_latest_view::\exposid{sentinel}}% +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class cache_latest_view::@\exposid{sentinel}@ { + sentinel_t @\exposid{end_}@ = sentinel_t(); // \expos + + constexpr explicit @\exposid{sentinel}@(cache_latest_view& parent); // \expos + + public: + @\exposid{sentinel}@() = default; + + constexpr sentinel_t base() const; + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); + + friend constexpr range_difference_t operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t>; + friend constexpr range_difference_t operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t>; + }; +} +\end{codeblock} + +\indexlibraryctor{cache_latest_view::\exposid{sentinel}}% +\begin{itemdecl} +constexpr explicit @\exposid{sentinel}@(cache_latest_view& parent); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{end_} with \tcode{ranges::end(parent.\exposid{base_})}. +\end{itemdescr} + +\indexlibrarymember{base}{cache_latest_view::\exposid{sentinel}}% +\begin{itemdecl} +constexpr sentinel_t base() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{end_}. +\end{itemdescr} + +\indexlibrarymember{operator==}{cache_latest_view::\exposid{iterator}}% +\indexlibrarymember{operator==}{cache_latest_view::\exposid{sentinel}}% +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} == y.\exposid{end_}}. +\end{itemdescr} + +\indexlibrarymember{operator-}{cache_latest_view::\exposid{iterator}}% +\indexlibrarymember{operator-}{cache_latest_view::\exposid{sentinel}}% +\begin{itemdecl} +friend constexpr range_difference_t operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} - y.\exposid{end_}}. +\end{itemdescr} + +\indexlibrarymember{operator-}{cache_latest_view::\exposid{iterator}}% +\indexlibrarymember{operator-}{cache_latest_view::\exposid{sentinel}}% +\begin{itemdecl} +friend constexpr range_difference_t operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{end_} - y.\exposid{current_}}. +\end{itemdescr} + +\rSec2[range.to.input]{To input view} + +\rSec3[range.to.input.overview]{Overview} + +\pnum +\tcode{to_input_view} presents a view of an underlying sequence +as an input-only non-common range. +\begin{note} +This is useful to avoid overhead +that can be necessary to provide support for the operations +needed for greater iterator strength. +\end{note} + +\pnum +The name \tcode{views::to_input} denotes +a range adaptor object\iref{range.adaptor.object}. +Let \tcode{E} be an expression and let \tcode{T} be \tcode{decltype((E))}. +The expression \tcode{views::to_input(E)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{views::all(E)} +if \tcode{T} models \libconcept{input_range}, +does not satisfy \libconcept{common_range}, and +does not satisfy \libconcept{forward_range}. +\item +Otherwise, \tcode{to_input_view(E)}. +\end{itemize} + +\rSec3[range.to.input.view]{Class template \tcode{to_input_view}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + class to_input_view : public view_interface> { + V @\exposid{base_}@ = V(); // \expos + + // \ref{range.to.input.iterator}, class template \tcode{to_input_view::\exposid{iterator}} + template class @\exposid{iterator}@; // \expos + + public: + to_input_view() requires @\libconcept{default_initializable}@ = default; + constexpr explicit to_input_view(V base); + + constexpr V base() const & requires @\libconcept{copy_constructible}@ { return @\exposid{base_}@; } + constexpr V base() && { return std::move(@\exposid{base_}@); } + + constexpr auto begin() requires (!@\exposconcept{simple-view}@); + constexpr auto begin() const requires @\libconcept{range}@; + + constexpr auto end() requires (!@\exposconcept{simple-view}@); + constexpr auto end() const requires @\libconcept{range}@; + + constexpr auto size() requires @\libconcept{sized_range}@; + constexpr auto size() const requires @\libconcept{sized_range}@; + }; + + template + to_input_view(R&&) -> to_input_view>; +} +\end{codeblock} + +\begin{itemdecl} +constexpr explicit to_input_view(V base); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{base_} with \tcode{std::move(base)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto begin() requires (!@\exposconcept{simple-view}@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(ranges::begin(\exposid{base_}));} +\end{itemdescr} + +\begin{itemdecl} +constexpr auto begin() const requires @\libconcept{range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{iterator}(ranges::begin(\exposid{base_}));} +\end{itemdescr} + +\begin{itemdecl} +constexpr auto end() requires (!@\exposconcept{simple-view}@); +constexpr auto end() const requires @\libconcept{range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::end(\exposid{base_});} +\end{itemdescr} + +\begin{itemdecl} +constexpr auto size() requires @\libconcept{sized_range}@; +constexpr auto size() const requires @\libconcept{sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::size(\exposid{base_});} +\end{itemdescr} + +\rSec3[range.to.input.iterator]{Class template \tcode{to_input_view::\exposid{iterator}}} + +\begin{codeblock} +namespace std::ranges { + template<@\libconcept{input_range}@ V> + requires @\libconcept{view}@ + template + class to_input_view::@\exposid{iterator}@ { + using @\exposid{Base}@ = @\exposid{maybe-const}@; // \expos + + iterator_t<@\exposid{Base}@> @\exposid{current_}@ = iterator_t<@\exposid{Base}@>(); // \expos + + constexpr explicit @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current); // \expos + + public: + using difference_type = range_difference_t<@\exposid{Base}@>; + using value_type = range_value_t<@\exposid{Base}@>; + using iterator_concept = input_iterator_tag; + + @\exposid{iterator}@() requires @\libconcept{default_initializable}@> = default; + + @\exposid{iterator}@(@\exposid{iterator}@&&) = default; + @\exposid{iterator}@& operator=(@\exposid{iterator}@&&) = default; + + constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; + + constexpr iterator_t<@\exposid{Base}@> base() &&; + constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; + + constexpr decltype(auto) operator*() const { return *@\exposid{current_}@; } + + constexpr @\exposid{iterator}@& operator++(); + constexpr void operator++(int); + + friend constexpr bool operator==(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y); + + friend constexpr difference_type operator-(const sentinel_t<@\exposid{Base}@>& y, const @\exposid{iterator}@& x) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; + friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; + + friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); + + friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) + requires @\libconcept{indirectly_swappable}@>; + }; +} +\end{codeblock} + +\begin{itemdecl} +constexpr explicit @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(current)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@(@\exposid{iterator}@ i) + requires Const && @\libconcept{convertible_to}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}. +\end{itemdescr} + +\begin{itemdecl} +constexpr iterator_t<@\exposid{Base}@> base() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::move(\exposid{current_)}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{current_}. +\end{itemdescr} + +\begin{itemdecl} +constexpr @\exposid{iterator}@& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +++@\exposid{current_}@; +return *this; +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +constexpr void operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{++*this;} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr bool operator==(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} == y}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr difference_type operator-(const sentinel_t<@\exposid{Base}@>& y, const @\exposid{iterator}@& x) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{y - x.\exposid{current_}}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y) + requires @\libconcept{sized_sentinel_for}@, iterator_t<@\exposid{Base}@>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.\exposid{current_} - y}. +\end{itemdescr} + +\begin{itemdecl} +friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i) + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return ranges::iter_move(i.\exposid{current_});} +\end{itemdescr} + +\begin{itemdecl} +friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_)}@)) + requires @\libconcept{indirectly_swappable}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_});} +\end{itemdescr} + +\rSec1[coro.generator]{Range generators} + +\rSec2[coroutine.generator.overview]{Overview} + +\pnum +Class template \tcode{generator} presents +a view of the elements yielded by the evaluation of a coroutine. + +\pnum +A \tcode{generator} generates a sequence of elements by +repeatedly resuming the coroutine from which it was returned. +Elements of the sequence are produced by the coroutine +each time a \tcode{co_yield} statement is evaluated. +When the \tcode{co_yield} statement is of the form +\tcode{co_yield elements_of(r)}, +each element of the range \tcode{r} +is successively produced as an element of the sequence. +\begin{example} +\begin{codeblock} +generator ints(int start = 0) { + while (true) + co_yield start++; +} + +void f() { + for (auto i : ints() | views::take(3)) + cout << i << ' '; // prints \tcode{0 1 2} +} +\end{codeblock} +\end{example} + +\rSec2[generator.syn]{Header \tcode{} synopsis} + +\indexheader{generator}% +\begin{codeblock} +namespace std { + // \ref{coro.generator.class}, class template \tcode{generator} + template + class generator; + + namespace pmr { + template + using generator = std::generator>; + } +} +\end{codeblock} + +\rSec2[coro.generator.class]{Class template \tcode{generator}} + +\begin{codeblock} +namespace std { + template + class @\libglobal{generator}@ : public ranges::view_interface> { + private: + using @\exposid{value}@ = conditional_t, remove_cvref_t, Val>; // \expos + using @\exposid{reference}@ = conditional_t, Ref&&, Ref>; // \expos + + // \ref{coro.generator.iterator}, class \tcode{generator::\exposid{iterator}} + class @\exposidnc{iterator}@; // \expos + + public: + using yielded = + conditional_t, @\exposid{reference}@, const @\exposid{reference}@&>; + + // \ref{coro.generator.promise}, class \tcode{generator::promise_type} + class promise_type; generator(const generator&) = delete; generator(generator&& other) noexcept; @@ -16873,7 +18028,7 @@ Initializes \exposid{coroutine_} with \tcode{exchange(other.\exposid{coroutine_}, \{\})} and \exposid{active_} with -\tcode{exchange(\brk{}other.active_, nullptr)}. +\tcode{exchange(\brk{}other.\exposid{active_}, nullptr)}. \pnum \begin{note} @@ -16977,8 +18132,8 @@ \begin{codeblock} namespace std { - template - class generator::promise_type { + template + class generator::promise_type { public: generator get_return_object() noexcept; @@ -16994,6 +18149,9 @@ template requires @\libconcept{same_as}@::yielded, yielded> auto yield_value(ranges::elements_of&&, Unused> g) noexcept; + template + requires @\libconcept{same_as}@::yielded, yielded> + auto yield_value(ranges::elements_of&, Unused> g) noexcept; template requires @\libconcept{convertible_to}@, yielded> @@ -17008,13 +18166,11 @@ requires @\libconcept{same_as}@ || @\libconcept{default_initializable}@; template - requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ - void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); + void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); template - requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ - void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, - const Args&...); + void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, + const Args&...); void operator delete(void* pointer, size_t size) noexcept; @@ -17121,6 +18277,9 @@ template requires @\libconcept{same_as}@::yielded, yielded> auto yield_value(ranges::elements_of&&, Unused> g) noexcept; +template + requires @\libconcept{same_as}@::yielded, yielded> + auto yield_value(ranges::elements_of&, Unused> g) noexcept; \end{itemdecl} \begin{itemdescr} @@ -17153,7 +18312,7 @@ \pnum \remarks -A \grammarterm{yield-expression} that calls this function +A \grammarterm{yield-expression} that calls one of these functions has type \tcode{void}\iref{expr.yield}. \end{itemdescr} @@ -17170,7 +18329,7 @@ Equivalent to: \begin{codeblock} auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t i, ranges::sentinel_t s) - -> generator, Alloc> { + -> generator { for (; i != s; ++i) { co_yield static_cast(*i); } @@ -17213,11 +18372,9 @@ requires @\libconcept{same_as}@ || @\libconcept{default_initializable}@; template - requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...); template - requires @\libconcept{same_as}@ || @\libconcept{convertible_to}@ void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, const Args&...); \end{itemdecl} @@ -17240,6 +18397,9 @@ \pnum \mandates \tcode{allocator_traits::pointer} is a pointer type. +For the overloads with a template parameter \tcode{Alloc}, +\tcode{\libconcept{same_as} || \libconcept{convertible_to}} +is modeled. \pnum \effects @@ -17280,8 +18440,8 @@ \begin{codeblock} namespace std { - template - class generator::@\exposid{iterator}@ { + template + class generator::@\exposid{iterator}@ { public: using value_type = @\exposid{value}@; using difference_type = ptrdiff_t; diff --git a/source/regex.tex b/source/regex.tex deleted file mode 100644 index bbec2e9f78..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; - [[nodiscard]] 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} -[[nodiscard]] 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/statements.tex b/source/statements.tex index 2b6bde2f3a..ba75c744d2 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -1,5 +1,5 @@ %!TEX root = std.tex -\rSec0[stmt.stmt]{Statements}% +\rSec0[stmt]{Statements}% \indextext{statement|(} \gramSec[gram.stmt]{Statements} @@ -9,7 +9,7 @@ \rSec1[stmt.pre]{Preamble} \pnum -Except as indicated, statements are executed in sequence. +Except as indicated, statements are executed in sequence\iref{intro.execution}. \begin{bnf} \nontermdef{statement}\br @@ -19,6 +19,7 @@ \opt{attribute-specifier-seq} selection-statement\br \opt{attribute-specifier-seq} iteration-statement\br \opt{attribute-specifier-seq} jump-statement\br + \opt{attribute-specifier-seq} assertion-statement\br declaration-statement\br \opt{attribute-specifier-seq} try-block \end{bnf} @@ -33,7 +34,8 @@ \begin{bnf} \nontermdef{condition}\br expression\br - \opt{attribute-specifier-seq} decl-specifier-seq declarator brace-or-equal-initializer + \opt{attribute-specifier-seq} decl-specifier-seq declarator brace-or-equal-initializer\br + structured-binding-declaration initializer \end{bnf} The optional \grammarterm{attribute-specifier-seq} appertains to the respective statement. @@ -86,8 +88,12 @@ The rules for \grammarterm{condition}{s} apply both to \grammarterm{selection-statement}{s}\iref{stmt.select} and to the \keyword{for} and \keyword{while} statements\iref{stmt.iter}. -A \grammarterm{condition} that is not an \grammarterm{expression} is a -declaration\iref{dcl.dcl}. +If a \grammarterm{structured-binding-declaration} +appears in a \grammarterm{condition}, +the \grammarterm{condition} is a structured binding declaration\iref{dcl.pre}. +A \grammarterm{condition} that is +neither an \grammarterm{expression} nor a structured binding declaration +is a declaration\iref{dcl}. The \grammarterm{declarator} shall not specify a function or an array. The \grammarterm{decl-specifier-seq} shall not define a class or enumeration. If the \keyword{auto} \grammarterm{type-specifier} appears in @@ -95,9 +101,16 @@ the type of the identifier being declared is deduced from the initializer as described in~\ref{dcl.spec.auto}. \pnum -The value of a \grammarterm{condition} that is an initialized declaration +The \defnadj{decision}{variable} of a \grammarterm{condition} +that is neither an \grammarterm{expression} nor a structured binding declaration +is the declared variable. +The decision variable of a \grammarterm{condition} +that is a structured binding declaration is specified in \ref{dcl.struct.bind}. + +\pnum +The value of a \grammarterm{condition} that is not an \grammarterm{expression} in a statement other than a \keyword{switch} statement is the value of the -declared variable +decision variable contextually converted to \tcode{bool}\iref{conv}. If that conversion is ill-formed, the program is ill-formed. @@ -116,7 +129,10 @@ it is interpreted as the latter. \pnum -In the \grammarterm{decl-specifier-seq} of a \grammarterm{condition}, each +In the \grammarterm{decl-specifier-seq} of a \grammarterm{condition}, +including that of any \grammarterm{structured-binding-declaration} of +the \grammarterm{condition}, +each \grammarterm{decl-specifier} shall be either a \grammarterm{type-specifier} or \keyword{constexpr}. @@ -211,14 +227,12 @@ \begin{bnf} \nontermdef{statement-seq}\br - statement\br - statement-seq statement + statement \opt{statement-seq} \end{bnf} \begin{bnf} \nontermdef{label-seq}\br - label\br - label-seq label + label \opt{label-seq} \end{bnf} A label at the end of a \grammarterm{compound-statement} @@ -267,7 +281,7 @@ \indextext{statement!\idxcode{if}} \pnum -If the condition\iref{stmt.pre} yields \tcode{true} the first +If the condition\iref{stmt.pre} yields \tcode{true}, the first substatement is executed. If the \keyword{else} part of the selection statement is present and the condition yields \tcode{false}, the second substatement is executed. If the first substatement is reached via a @@ -408,10 +422,9 @@ several statements depending on the value of a condition. \pnum -The value of a \grammarterm{condition} -that is an initialized declaration -is the value of the declared variable, -or the value of the \grammarterm{expression} otherwise. +If the \grammarterm{condition} is an \grammarterm{expression}, +the value of the condition is the value of the \grammarterm{expression}; +otherwise, it is the value of the decision variable. The value of the condition shall be of integral type, enumeration type, or class type. If of class type, the condition is contextually implicitly converted\iref{conv} to @@ -567,8 +580,9 @@ evaluates to \tcode{true}. The \grammarterm{statement} of a trivial infinite loop is replaced with a call to the function \tcode{std::this_thread::yield}\iref{thread.thread.this}; -it is implementation-defined whether this replacement occurs -on freestanding implementations. +it is \impldef{whether freestanding implementations replace the \grammarterm{statement} +of a trivial infinite loop with a call to the function \tcode{std::this_thread::yield}} +whether this replacement occurs on freestanding implementations. \begin{note} In a freestanding environment, concurrent forward progress is not guaranteed; @@ -934,6 +948,16 @@ by the operand of the \tcode{return} statement, which, in turn, is sequenced before the destruction of local variables\iref{stmt.jump} of the block enclosing the \tcode{return} statement. +\begin{note} +These operations +are sequenced before the destruction of local variables +in each remaining enclosing block of the function\iref{stmt.dcl}, +which, in turn, +is sequenced before the evaluation of +postcondition assertions of the function\iref{dcl.contract.func}, +which, in turn, +is sequenced before the destruction of function parameters\iref{expr.call}. +\end{note} \pnum In a function whose return type is a reference, @@ -1019,6 +1043,48 @@ \indextext{label}% label\iref{stmt.label} located in the current function. +\rSec1[stmt.contract.assert]{Assertion statement} + +\begin{bnf} +\nontermdef{assertion-statement}\br + \terminal{contract_assert} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)} \terminal{;} +\end{bnf} + +\pnum +\indexdefn{contract assertion!statement|see{assertion, statement}} +\indextext{assertion!statement} +An \grammarterm{assertion-statement} +introduces a contract assertion\iref{basic.contract}. +The optional \grammarterm{attribute-specifier-seq} +appertains to the introduced contract assertion. + +\pnum +The predicate\iref{basic.contract.general} +of an \grammarterm{assertion-statement} +is its \grammarterm{conditional-expression} +contextually converted to \tcode{bool}. + +\pnum +The evaluation of consecutive \grammarterm{assertion-statement}s +is an evaluation in sequence\iref{basic.contract.eval} of +the contract assertions introduced +by those \grammarterm{assertion-statement}s. +\begin{note} +A sequence of \grammarterm{assertion-statement}s +can thus be repeatedly evaluated as a group. +\begin{example} +\begin{codeblock} +int f(int i) +{ + contract_assert(i == 0); // \#1 + contract_assert(i >= 0); // \#2 + return 0; +} +int g = f(0); // can evaluate \#1, \#2, \#1, \#2 +\end{codeblock} +\end{example} +\end{note} + \rSec1[stmt.dcl]{Declaration statement}% \indextext{statement!declaration} @@ -1147,7 +1213,7 @@ of many examples. \begin{example} Assuming \tcode{T} is a -\grammarterm{simple-type-specifier}\iref{dcl.type}, +\grammarterm{simple-type-specifier}\iref{dcl.type.simple}, \begin{codeblock} T(a)->m = 7; // expression-statement diff --git a/source/std.tex b/source/std.tex index c97d4302bd..0170e31451 100644 --- a/source/std.tex +++ b/source/std.tex @@ -24,6 +24,7 @@ \usepackage{color} % define colors for strikeouts and underlines \usepackage{amsmath} % additional math symbols \usepackage{mathrsfs} % mathscr font +\usepackage{bm} \usepackage[final]{microtype} \usepackage[splitindex,original]{imakeidx} \usepackage{multicol} @@ -41,9 +42,11 @@ linktocpage=true, 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 +\usepackage{environ} \usepackage{expl3} \usepackage{xparse} \usepackage{xstring} @@ -54,6 +57,10 @@ \renewcommand\RSsmallest{5.5pt} % smallest font size for relsize +% Begin grammar extraction... +\newwrite\gramout +\immediate\openout\gramout=std-gram.ext + \input{layout} \input{styles} \input{macros} @@ -85,6 +92,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} @@ -122,21 +133,22 @@ \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} %%-------------------------------------------------- %% appendices \appendix +\chapterstyle{cppannex} % \include and \addtocontents don't mix; see % https://tex.stackexchange.com/questions/13914/toc-numbering-problem @@ -146,6 +158,9 @@ \numberwithin{table}{chapter} +% ... end grammar extraction. +\immediate\closeout\gramout + \include{grammar} \include{limits} \include{compatibility} diff --git a/source/strings.tex b/source/strings.tex index 4493b5d463..a9615c7d91 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -5,7 +5,8 @@ \pnum This Clause describes components for manipulating sequences of -any non-array trivial standard-layout\iref{term.standard.layout.type} type. +any non-array trivially copyable standard-layout\iref{term.standard.layout.type} type \tcode{T} +where \tcode{is_trivially_default_constructible_v} is \tcode{true}. Such types are called \defnx{char-like types}{char-like type}, and objects of char-like types are called \defnx{char-like objects}{char-like object} or @@ -21,9 +22,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} @@ -108,7 +107,7 @@ denotes an lvalue of type \tcode{C}. No expression which is part of the character traits requirements -specified in this subclause \ref{char.traits.require} +specified in \ref{char.traits.require} shall exit via an exception. \begin{libreqtab4d} @@ -124,15 +123,15 @@ & & \chdr{pre-/post-condition} & \\ \capsep \endhead \tcode{X::char_type} & \tcode{C} & - & compile-time \\ \rowsep + & \\ \rowsep \tcode{X::int_type} & & -(described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep +(described in~\ref{char.traits.typedefs}) & \\ \rowsep \tcode{X::off_type} & & -(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & compile-time \\ \rowsep +(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & \\ \rowsep \tcode{X::pos_type} & & -(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & compile-time \\ \rowsep +(described in~\ref{iostreams.limits.pos} and \ref{iostream.forward}) & \\ \rowsep \tcode{X::state_type} & & -(described in~\ref{char.traits.typedefs}) & compile-time \\ \rowsep +(described in~\ref{char.traits.typedefs}) & \\ \rowsep \tcode{X::eq(c,d)} & \tcode{bool} & \returns whether \tcode{c} is to be treated as equal to \tcode{d}. & constant \\ \rowsep @@ -141,31 +140,31 @@ whether \tcode{c} is to be treated as less than \tcode{d}. & constant \\ \rowsep \tcode{X::compare(p,q,n)} & \tcode{int} & \returns -\tcode{0} if for each \tcode{i} in \tcode{[0,n)}, \tcode{X::eq(p[i],q[i])} -is \tcode{true}; else, a negative value if, for some \tcode{j} in \tcode{[0,n)}, -\tcode{X::lt(p[j],q[j])} is \tcode{true} and for each \tcode{i} in \tcode{[0,j)} +\tcode{0} if for each \tcode{i} in \range{0}{n}, \tcode{X::eq(p[i],q[i])} +is \tcode{true}; else, a negative value if, for some \tcode{j} in \range{0}{n}, +\tcode{X::lt(p[j],q[j])} is \tcode{true} and for each \tcode{i} in \range{0}{j} \tcode{X::eq(p[i],q[i])} is \tcode{true}; else a positive value. & linear \\ \rowsep \tcode{X::length(p)} & \tcode{size_t} & \returns the smallest \tcode{i} such that \tcode{X::eq(p[i],charT())} is \tcode{true}. & linear \\ \rowsep \tcode{X::find(p,n,c)} & \tcode{const X::char_type*} & \returns -the smallest \tcode{q} in \tcode{[p,p+n)} such that +the smallest \tcode{q} in \range{p}{p+n} such that \tcode{X::eq(*q,c)} is \tcode{true}, \tcode{nullptr} otherwise. & linear \\ \rowsep \tcode{X::move(s,p,n)} & \tcode{X::char_type*} & -for each \tcode{i} in \tcode{[0,n)}, performs \tcode{X::assign(s[i],p[i])}. -Copies correctly even where the ranges \tcode{[p,p+n)} and \tcode{[s,s+n)} overlap.\br \returns \tcode{s}. & linear \\ \rowsep +for each \tcode{i} in \range{0}{n}, performs \tcode{X::assign(s[i],p[i])}. +Copies correctly even where the ranges \range{p}{p+n} and \range{s}{s+n} overlap.\br \returns \tcode{s}. & linear \\ \rowsep \tcode{X::copy(s,p,n)} & \tcode{X::char_type*} & \expects The ranges \range{p}{p+n} and \range{s}{s+n} do not overlap.\par \returns \tcode{s}.\br for each \tcode{i} in -\tcode{[0,n)}, performs \tcode{X::assign(s[i],p[i])}. & linear \\ \rowsep +\range{0}{n}, performs \tcode{X::assign(s[i],p[i])}. & linear \\ \rowsep \tcode{X::assign(r,d)} & (not used) & assigns \tcode{r=d}. & constant \\ \rowsep \tcode{X::assign\-(s,n,c)} & \tcode{X::char_type*} & -for each \tcode{i} in \tcode{[0,n)}, performs +for each \tcode{i} in \range{0}{n}, performs \tcode{X::assign(s[i],c)}.\br \returns \tcode{s}. & linear \\ \rowsep @@ -201,7 +200,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 +306,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. @@ -659,7 +658,7 @@ constexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; - [[nodiscard]] constexpr bool empty() const noexcept; + constexpr bool empty() const noexcept; // \ref{string.view.access}, element access constexpr const_reference operator[](size_type pos) const; @@ -1021,7 +1020,7 @@ \indexlibrarymember{empty}{basic_string_view}% \begin{itemdecl} -[[nodiscard]] constexpr bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -1039,8 +1038,11 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos < size()}. +\hardexpects +\tcode{pos < size()} is \tcode{true}. +\begin{note} +This precondition is stronger than the one on \tcode{basic_string::operator[]}. +\end{note} \pnum \returns @@ -1049,12 +1051,6 @@ \pnum \throws Nothing. - -\pnum -\begin{note} -Unlike \tcode{basic_string::operator[]}, -\tcode{basic_string_view::operator[](size())} has undefined behavior instead of returning \tcode{charT()}. -\end{note} \end{itemdescr} \indexlibrarymember{at}{basic_string_view}% @@ -1079,8 +1075,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{!empty()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum \returns @@ -1098,8 +1094,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{!empty()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum \returns @@ -1137,8 +1133,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{n <= size()}. +\hardexpects +\tcode{n <= size()} is \tcode{true}. \pnum \effects @@ -1152,8 +1148,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{n <= size()}. +\hardexpects +\tcode{n <= size()} is \tcode{true}. \pnum \effects @@ -1667,7 +1663,7 @@ \pnum \returns -\tcode{os} +\tcode{os}. \end{itemdescr} \rSec2[string.view.hash]{Hash support} @@ -2123,7 +2119,7 @@ constexpr void reserve(size_type res_arg); constexpr void shrink_to_fit(); constexpr void clear() noexcept; - [[nodiscard]] constexpr bool empty() const noexcept; + constexpr bool empty() const noexcept; // \ref{string.access}, element access constexpr const_reference operator[](size_type pos) const; @@ -3074,7 +3070,7 @@ \indexlibrarymember{empty}{basic_string}% \begin{itemdecl} -[[nodiscard]] constexpr bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3094,8 +3090,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos <= size()}. +\hardexpects +\tcode{pos <= size()} is \tcode{true}. \pnum \returns @@ -3139,8 +3135,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{!empty()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum \effects @@ -3155,8 +3151,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{!empty()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum \effects @@ -3738,7 +3734,7 @@ \pnum \returns -\tcode{*this} +\tcode{*this}. \pnum \throws @@ -3918,7 +3914,7 @@ \pnum \effects Removes the characters in the range -\tcode{[first, last)}. +\range{first}{last}. \pnum \returns @@ -3940,8 +3936,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{!empty()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum \effects @@ -5443,106 +5439,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}% @@ -5616,9 +5512,11 @@ \indextext{signal-safe!\idxcode{memcpy}}% \indextext{signal-safe!\idxcode{memmove}}% The functions \tcode{memcpy} and \tcode{memmove} are signal-safe\iref{support.signal}. -Both functions implicitly create objects\iref{intro.object} +Each of these functions implicitly creates objects\iref{intro.object} in the destination region of storage immediately prior to copying the sequence of characters to the destination. +Each of these functions returns a pointer to a suitable created object, if any, +otherwise the value of the first parameter. \pnum \begin{note} @@ -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 8d771e10db..224c99d1e1 100644 --- a/source/styles.tex +++ b/source/styles.tex @@ -5,11 +5,11 @@ % footnotes %%-------------------------------------------------- -%% create chapter style +%% create chapter styles \makechapterstyle{cppstd}{% - \renewcommand{\beforechapskip}{\onelineskip} - \renewcommand{\afterchapskip}{\onelineskip} + \setlength{\beforechapskip}{\onelineskip} + \setlength{\afterchapskip}{\onelineskip} \renewcommand{\chapternamenum}{} \renewcommand{\chapnamefont}{\chaptitlefont} \renewcommand{\chapnumfont}{\chaptitlefont} @@ -17,14 +17,24 @@ \renewcommand{\afterchapternum}{} } +\makechapterstyle{cppannex}{% + \setlength{\beforechapskip}{\onelineskip} + \setlength{\afterchapskip}{\onelineskip} + \renewcommand{\chapternamenum}{} + \renewcommand{\chapnamefont}{\chaptitlefont} + \renewcommand{\chapnumfont}{\chaptitlefont} + \renewcommand{\printchapternum}{\chapnumfont\centering\thechapter\protect\\} + \renewcommand{\afterchapternum}{} +} + %%-------------------------------------------------- %% create page styles \makepagestyle{cpppage} -\makeevenhead{cpppage}{\copyright\,\textsc{ISO/IEC}}{}{\textbf{\docno}} -\makeoddhead{cpppage}{\copyright\,\textsc{ISO/IEC}}{}{\textbf{\docno}} -\makeevenfoot{cpppage}{\leftmark}{}{\thepage} -\makeoddfoot{cpppage}{\leftmark}{}{\thepage} +\makeevenhead{cpppage}{}{\textbf{\docno}}{} + \makeoddhead{cpppage}{}{\textbf{\docno}}{} +\makeevenfoot{cpppage}{\leftmark\\\mbox{}}{}{\copyright\,\textsc{ISO/IEC}\\\thepage} + \makeoddfoot{cpppage}{\leftmark\\\mbox{}}{}{\copyright\,\textsc{ISO/IEC}\\\thepage} \makeatletter \makepsmarks{cpppage}{% @@ -86,7 +96,7 @@ %%-------------------------------------------------- % set heading style for annexes -\newcommand{\Annex}[3]{\chapter[#2]{(#3)\protect\\#2\hfill[#1]}\relax\annexlabel{#1}} +\newcommand{\Annex}[3]{\chapter[#2]{\textnormal{(#3)}\protect\\[3ex]#2\hfill[#1]}\relax\annexlabel{#1}} \newcommand{\infannex}[2]{\addxref{#1}\Annex{#1}{#2}{informative}} \newcommand{\normannex}[2]{\addxref{#1}\Annex{#1}{#2}{normative}} @@ -111,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 @@ -165,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 9924cbdabd..7d53612aad 100644 --- a/source/support.tex +++ b/source/support.tex @@ -17,6 +17,7 @@ functions supporting start and termination of a \Cpp{} program, support for dynamic memory management, support for dynamic type identification, +support for contract-violation handling, support for exception processing, support for initializer lists, and other runtime support, as summarized in \tref{support.summary}. @@ -29,10 +30,11 @@ \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.contract} & Contract-violation handling & \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 & @@ -333,9 +335,10 @@ \pnum The type \indexlibraryglobal{max_align_t}% -\tcode{max_align_t} is a trivial standard-layout type whose alignment requirement +\tcode{max_align_t} is a trivially copyable standard-layout type whose alignment requirement is at least as great as that of every scalar type, and whose alignment requirement is supported in every context\iref{basic.align}. +\tcode{std::is_trivially_default_constructible_v} is \tcode{true}. \xrefc{7.19} @@ -546,7 +549,7 @@ after inclusion of any member of the set of library headers indicated in the corresponding comment in this synopsis. \begin{note} -Future revisions of \Cpp{} might replace +Future revisions of this document might replace the values of these macros with greater values. \end{note} @@ -557,6 +560,7 @@ // also in \libheader{algorithm}, \libheader{ranges}, \libheader{string}, \libheader{deque}, \libheader{list}, \libheader{forward_list}, \libheader{vector} #define @\defnlibxname{cpp_lib_algorithm_iterator_requirements}@ 202207L // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory} +#define @\defnlibxname{cpp_lib_aligned_accessor}@ 202411L // also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_allocate_at_least}@ 202302L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_allocator_traits_is_always_equal}@ 201411L // freestanding, also in \libheader{memory}, \libheader{scoped_allocator}, \libheader{string}, \libheader{deque}, \libheader{forward_list}, \libheader{list}, @@ -575,7 +579,7 @@ #define @\defnlibxname{cpp_lib_atomic_is_always_lock_free}@ 201603L // freestanding, also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_lock_free_type_aliases}@ 201907L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_min_max}@ 202403L // freestanding, also in \libheader{atomic} -#define @\defnlibxname{cpp_lib_atomic_ref}@ 201806L // freestanding, also in \libheader{atomic} +#define @\defnlibxname{cpp_lib_atomic_ref}@ 202411L // freestanding, also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_shared_ptr}@ 201711L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // freestanding, also in \libheader{atomic}, \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // freestanding, also in \libheader{atomic} @@ -596,34 +600,51 @@ #define @\defnlibxname{cpp_lib_chrono}@ 202306L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_chrono_udls}@ 201304L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_clamp}@ 201603L // also in \libheader{algorithm} -#define @\defnlibxname{cpp_lib_common_reference}@ 202302L // also in \libheader{type_traits} -#define @\defnlibxname{cpp_lib_common_reference_wrapper}@ 202302L // also in \libheader{functional} +#define @\defnlibxname{cpp_lib_common_reference}@ 202302L // freestanding, also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_common_reference_wrapper}@ 202302L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202207L // freestanding, also in \libheader{concepts}, \libheader{compare} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 202306L // also in \libheader{algorithm}, \libheader{utility} +#define @\defnlibxname{cpp_lib_constexpr_atomic}@ 202411L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202207L // also in \libheader{bitset} -#define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} +#define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // freestanding, also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202306L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 202306L // also in \libheader{complex} +#define @\defnlibxname{cpp_lib_constexpr_deque}@ 202502L // also in \libheader{deque} #define @\defnlibxname{cpp_lib_constexpr_dynamic_alloc}@ 201907L // also in \libheader{memory} +#define @\defnlibxname{cpp_lib_constexpr_exceptions}@ 202502L + // also in \libheader{exception}, \libheader{stdexcept}, \libheader{expected}, \libheader{optional}, \libheader{variant}, and \libheader{format} +#define @\defnlibxname{cpp_lib_constexpr_flat_map}@ 202502L // also in \libheader{flat_map} +#define @\defnlibxname{cpp_lib_constexpr_flat_set}@ 202502L // also in \libheader{flat_set} +#define @\defnlibxname{cpp_lib_constexpr_forward_list}@ 202502L // also in \libheader{forward_list} #define @\defnlibxname{cpp_lib_constexpr_functional}@ 201907L // freestanding, also in \libheader{functional} +#define @\defnlibxname{cpp_lib_constexpr_inplace_vector}@ 202502L // also in \libheader{inplace_vector} #define @\defnlibxname{cpp_lib_constexpr_iterator}@ 201811L // freestanding, also in \libheader{iterator} +#define @\defnlibxname{cpp_lib_constexpr_list}@ 202502L // also in \libheader{list} +#define @\defnlibxname{cpp_lib_constexpr_map}@ 202502L // also in \libheader{map} #define @\defnlibxname{cpp_lib_constexpr_memory}@ 202202L // freestanding, also in \libheader{memory} +#define @\defnlibxname{cpp_lib_constexpr_new}@ 202406L // freestanding, also in \libheader{new} #define @\defnlibxname{cpp_lib_constexpr_numeric}@ 201911L // also in \libheader{numeric} +#define @\defnlibxname{cpp_lib_constexpr_queue}@ 202502L // also in \libheader{queue} +#define @\defnlibxname{cpp_lib_constexpr_set}@ 202502L // also in \libheader{set} +#define @\defnlibxname{cpp_lib_constexpr_stack}@ 202502L // also in \libheader{stack} #define @\defnlibxname{cpp_lib_constexpr_string}@ 201907L // also in \libheader{string} #define @\defnlibxname{cpp_lib_constexpr_string_view}@ 201811L // also in \libheader{string_view} #define @\defnlibxname{cpp_lib_constexpr_tuple}@ 201811L // freestanding, also in \libheader{tuple} #define @\defnlibxname{cpp_lib_constexpr_typeinfo}@ 202106L // freestanding, also in \libheader{typeinfo} +#define @\defnlibxname{cpp_lib_constexpr_unordered_map}@ 202502L // also in \libheader{unordered_map} +#define @\defnlibxname{cpp_lib_constexpr_unordered_set}@ 202502L // also in \libheader{unordered_set} #define @\defnlibxname{cpp_lib_constexpr_utility}@ 201811L // freestanding, also in \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_vector}@ 201907L // also in \libheader{vector} -#define @\defnlibxname{cpp_lib_constrained_equality}@ 202403L // freestanding, - // also in \libheader{utility}, \libheader{tuple}, \libheader{optional}, \libheader{variant} +#define @\defnlibxname{cpp_lib_constrained_equality}@ 202411L // freestanding, + // also in \libheader{utility}, \libheader{tuple}, \libheader{optional}, \libheader{variant}, \libheader{expected} #define @\defnlibxname{cpp_lib_containers_ranges}@ 202202L // also in \libheader{vector}, \libheader{list}, \libheader{forward_list}, \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}, // \libheader{deque}, \libheader{queue}, \libheader{stack}, \libheader{string} +#define @\defnlibxname{cpp_lib_contracts}@ 202502L // freestanding, also in \libheader{contracts} #define @\defnlibxname{cpp_lib_copyable_function}@ 202306L // also in \libheader{functional} -#define @\defnlibxname{cpp_lib_coroutine}@ 201902L // also in \libheader{coroutine} +#define @\defnlibxname{cpp_lib_coroutine}@ 201902L // freestanding, also in \libheader{coroutine} #define @\defnlibxname{cpp_lib_debugging}@ 202403L // freestanding, also in \libheader{debugging} #define @\defnlibxname{cpp_lib_destroying_delete}@ 201806L // freestanding, also in \libheader{new} #define @\defnlibxname{cpp_lib_enable_shared_from_this}@ 201603L // also in \libheader{memory} @@ -643,7 +664,7 @@ #define @\defnlibxname{cpp_lib_format_uchar}@ 202311L // also in \libheader{format} #define @\defnlibxname{cpp_lib_formatters}@ 202302L // also in \libheader{stacktrace}, \libheader{thread} #define @\defnlibxname{cpp_lib_forward_like}@ 202207L // freestanding, also in \libheader{utility} -#define @\defnlibxname{cpp_lib_freestanding_algorithm}@ 202311L // freestanding, also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_freestanding_algorithm}@ 202502L // freestanding, also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_freestanding_array}@ 202311L // freestanding, also in \libheader{array} #define @\defnlibxname{cpp_lib_freestanding_char_traits}@ 202306L // freestanding, also in \libheader{string} #define @\defnlibxname{cpp_lib_freestanding_charconv}@ 202306L // freestanding, also in \libheader{charconv} @@ -652,15 +673,17 @@ #define @\defnlibxname{cpp_lib_freestanding_cwchar}@ 202306L // freestanding, also in \libheader{cwchar} #define @\defnlibxname{cpp_lib_freestanding_errc}@ 202306L // freestanding, also in \libheader{cerrno}, \libheader{system_error} +#define @\defnlibxname{cpp_lib_freestanding_execution}@ 202502L // freestanding, also in \libheader{execution} #define @\defnlibxname{cpp_lib_freestanding_expected}@ 202311L // freestanding, also in \libheader{expected} #define @\defnlibxname{cpp_lib_freestanding_feature_test_macros}@ 202306L // freestanding #define @\defnlibxname{cpp_lib_freestanding_functional}@ 202306L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_freestanding_iterator}@ 202306L // freestanding, also in \libheader{iterator} #define @\defnlibxname{cpp_lib_freestanding_mdspan}@ 202311L // freestanding, also in \libheader{mdspan} -#define @\defnlibxname{cpp_lib_freestanding_memory}@ 202306L // freestanding, also in \libheader{memory} -#define @\defnlibxname{cpp_lib_freestanding_numeric}@ 202311L // freestanding, also in \libheader{numeric} +#define @\defnlibxname{cpp_lib_freestanding_memory}@ 202502L // freestanding, also in \libheader{memory} +#define @\defnlibxname{cpp_lib_freestanding_numeric}@ 202502L // freestanding, also in \libheader{numeric} #define @\defnlibxname{cpp_lib_freestanding_operator_new}@ @\seebelow@ // freestanding, also in \libheader{new} #define @\defnlibxname{cpp_lib_freestanding_optional}@ 202311L // freestanding, also in \libheader{optional} +#define @\defnlibxname{cpp_lib_freestanding_random}@ 202502L // freestanding, also in \libheader{random} #define @\defnlibxname{cpp_lib_freestanding_ranges}@ 202306L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_freestanding_ratio}@ 202306L // freestanding, also in \libheader{ratio} #define @\defnlibxname{cpp_lib_freestanding_string_view}@ 202311L // freestanding, also in \libheader{string_view} @@ -677,9 +700,12 @@ #define @\defnlibxname{cpp_lib_hardware_interference_size}@ 201703L // freestanding, also in \libheader{new} #define @\defnlibxname{cpp_lib_has_unique_object_representations}@ 201606L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_hazard_pointer}@ 202306L // also in \libheader{hazard_pointer} +#define @\defnlibxname{cpp_lib_hive}@ 202502L // also in \libheader{hive} #define @\defnlibxname{cpp_lib_hypot}@ 201603L // also in \libheader{cmath} #define @\defnlibxname{cpp_lib_incomplete_container_elements}@ 201505L // also in \libheader{forward_list}, \libheader{list}, \libheader{vector} +#define @\defnlibxname{cpp_lib_indirect}@ 202502L // also in \libheader{memory} +#define @\defnlibxname{cpp_lib_inplace_vector}@ 202406L // also in \libheader{inplace_vector} #define @\defnlibxname{cpp_lib_int_pow2}@ 202002L // freestanding, also in \libheader{bit} #define @\defnlibxname{cpp_lib_integer_comparison_functions}@ 202002L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_integer_sequence}@ 201304L // freestanding, also in \libheader{utility} @@ -691,19 +717,21 @@ #define @\defnlibxname{cpp_lib_is_aggregate}@ 201703L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_constant_evaluated}@ 201811L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_final}@ 201402L // freestanding, also in \libheader{type_traits} -#define @\defnlibxname{cpp_lib_is_implicit_lifetime}@ 202302L // also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_implicit_lifetime}@ 202302L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_invocable}@ 201703L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_layout_compatible}@ 201907L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_nothrow_convertible}@ 201806L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_null_pointer}@ 201309L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_pointer_interconvertible}@ 201907L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_scoped_enum}@ 202011L // freestanding, also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_sufficiently_aligned}@ 202411L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_is_swappable}@ 201603L // freestanding, also in \libheader{type_traits} -#define @\defnlibxname{cpp_lib_is_within_lifetime}@ 202306L // also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_virtual_base_of}@ 202406L // freestanding, also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_within_lifetime}@ 202306L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_jthread}@ 201911L // also in \libheader{stop_token}, \libheader{thread} #define @\defnlibxname{cpp_lib_latch}@ 201907L // also in \libheader{latch} #define @\defnlibxname{cpp_lib_launder}@ 201606L // freestanding, also in \libheader{new} -#define @\defnlibxname{cpp_lib_linalg}@ 202311L // also in \libheader{linalg} +#define @\defnlibxname{cpp_lib_linalg}@ 202412L // also in \libheader{linalg} #define @\defnlibxname{cpp_lib_list_remove_return_type}@ 201806L // also in \libheader{forward_list}, \libheader{list} #define @\defnlibxname{cpp_lib_logical_traits}@ 201510L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_make_from_tuple}@ 201606L // freestanding, also in \libheader{tuple} @@ -712,7 +740,7 @@ #define @\defnlibxname{cpp_lib_map_try_emplace}@ 201411L // also in \libheader{map} #define @\defnlibxname{cpp_lib_math_constants}@ 201907L // also in \libheader{numbers} #define @\defnlibxname{cpp_lib_math_special_functions}@ 201603L // also in \libheader{cmath} -#define @\defnlibxname{cpp_lib_mdspan}@ 202207L // also in \libheader{mdspan} +#define @\defnlibxname{cpp_lib_mdspan}@ 202406L // freestanding, also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_memory_resource}@ 201603L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_modules}@ 202207L // freestanding #define @\defnlibxname{cpp_lib_move_iterator_concept}@ 202207L // freestanding, also in \libheader{iterator} @@ -725,35 +753,41 @@ #define @\defnlibxname{cpp_lib_not_fn}@ 202306L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_null_iterators}@ 201304L // freestanding, also in \libheader{iterator} #define @\defnlibxname{cpp_lib_optional}@ 202110L // also in \libheader{optional} +#define @\defnlibxname{cpp_lib_optional_range_support}@ 202406L // freestanding, also in \libheader{optional} #define @\defnlibxname{cpp_lib_out_ptr}@ 202311L // freestanding, also in \libheader{memory} #define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric} +#define @\defnlibxname{cpp_lib_philox_engine}@ 202406L // also in \libheader{random} +#define @\defnlibxname{cpp_lib_polymorphic}@ 202502L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} -#define @\defnlibxname{cpp_lib_print}@ 202403L // also in \libheader{print}, \libheader{ostream} +#define @\defnlibxname{cpp_lib_print}@ 202406L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} -#define @\defnlibxname{cpp_lib_ranges}@ 202302L +#define @\defnlibxname{cpp_lib_ranges}@ 202406L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202311L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // freestanding, also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_cache_latest}@ 202411L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_cartesian_product}@ 202207L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // freestanding, also in \libheader{ranges} -#define @\defnlibxname{cpp_lib_ranges_concat}@ 202403L // also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_concat}@ 202403L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} -#define @\defnlibxname{cpp_lib_ranges_enumerate}@ 202302L // also in \libheader{ranges}, \libheader{version} +#define @\defnlibxname{cpp_lib_ranges_enumerate}@ 202302L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_fold}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_generate_random}@ 202403L // also in \libheader{random} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_repeat}@ 202207L // freestanding, also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_reserve_hint}@ 202502L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_stride}@ 202207L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // freestanding, also in \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_to_input}@ 202502L // freestanding, also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // freestanding, also in \libheader{ranges}, \libheader{tuple}, \libheader{utility} -#define @\defnlibxname{cpp_lib_ratio}@ 202306L // also in \libheader{ratio} -#define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} +#define @\defnlibxname{cpp_lib_ratio}@ 202306L // freestanding, also in \libheader{ratio} +#define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 202411L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_rcu}@ 202306L // also in \libheader{rcu} #define @\defnlibxname{cpp_lib_reference_from_temporary}@ 202202L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_reference_wrapper}@ 202403L // freestanding, also in \libheader{functional} @@ -765,16 +799,19 @@ #define @\defnlibxname{cpp_lib_saturation_arithmetic}@ 202311L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_scoped_lock}@ 201703L // also in \libheader{mutex} #define @\defnlibxname{cpp_lib_semaphore}@ 201907L // also in \libheader{semaphore} +#define @\defnlibxname{cpp_lib_senders}@ 202406L // also in \libheader{execution} #define @\defnlibxname{cpp_lib_shared_mutex}@ 201505L // also in \libheader{shared_mutex} #define @\defnlibxname{cpp_lib_shared_ptr_arrays}@ 201707L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex} #define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_simd}@ 202502L // also in \libheader{simd} +#define @\defnlibxname{cpp_lib_simd_complex}@ 202502L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_smart_ptr_owner_equality}@ 202306L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location} #define @\defnlibxname{cpp_lib_span}@ 202311L // freestanding, also in \libheader{span} -#define @\defnlibxname{cpp_lib_span_initializer_list}@ 202311L // also in \libheader{span} +#define @\defnlibxname{cpp_lib_span_initializer_list}@ 202311L // freestanding, also in \libheader{span} #define @\defnlibxname{cpp_lib_spanstream}@ 202106L // also in \libheader{spanstream} #define @\defnlibxname{cpp_lib_ssize}@ 201902L // freestanding, also in \libheader{iterator} #define @\defnlibxname{cpp_lib_sstream_from_string_view}@ 202306L // also in \libheader{sstream} @@ -786,18 +823,20 @@ #define @\defnlibxname{cpp_lib_string_resize_and_overwrite}@ 202110L // also in \libheader{string} #define @\defnlibxname{cpp_lib_string_udls}@ 201304L // also in \libheader{string} #define @\defnlibxname{cpp_lib_string_view}@ 202403L // also in \libheader{string}, \libheader{string_view} -#define @\defnlibxname{cpp_lib_submdspan}@ 202403L // also in \libheader{mdspan} +#define @\defnlibxname{cpp_lib_submdspan}@ 202411L // freestanding, also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_syncbuf}@ 201803L // also in \libheader{syncstream} #define @\defnlibxname{cpp_lib_text_encoding}@ 202306L // also in \libheader{text_encoding} #define @\defnlibxname{cpp_lib_three_way_comparison}@ 201907L // freestanding, also in \libheader{compare} #define @\defnlibxname{cpp_lib_to_address}@ 201711L // freestanding, also in \libheader{memory} -#define @\defnlibxname{cpp_lib_to_array}@ 201907L // also in \libheader{array} +#define @\defnlibxname{cpp_lib_to_array}@ 201907L // freestanding, also in \libheader{array} #define @\defnlibxname{cpp_lib_to_chars}@ 202306L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_to_string}@ 202306L // also in \libheader{string} #define @\defnlibxname{cpp_lib_to_underlying}@ 202102L // freestanding, also in \libheader{utility} #define @\defnlibxname{cpp_lib_transformation_trait_aliases}@ 201304L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_transparent_operators}@ 201510L // freestanding, also in \libheader{memory}, \libheader{functional} +#define @\defnlibxname{cpp_lib_trivially_relocatable}@ 202502L + // freestanding, also in \libheader{memory}, \libheader{type_traits} #define @\defnlibxname{cpp_lib_tuple_element_t}@ 201402L // freestanding, also in \libheader{tuple} #define @\defnlibxname{cpp_lib_tuple_like}@ 202311L // also in \libheader{utility}, \libheader{tuple}, \libheader{map}, \libheader{unordered_map} @@ -812,6 +851,25 @@ #define @\defnlibxname{cpp_lib_void_t}@ 201411L // freestanding, also in \libheader{type_traits} \end{codeblock} +\pnum +Additionally, each of the following macros is defined in a hardened implementation: +\begin{codeblock} +#define @\defnlibxname{cpp_lib_hardened_array}@ 202502L // also in \libheader{array} +#define @\defnlibxname{cpp_lib_hardened_basic_string}@ 202502L // also in \libheader{string} +#define @\defnlibxname{cpp_lib_hardened_basic_string_view}@ 202502L // also in \libheader{string_view} +#define @\defnlibxname{cpp_lib_hardened_bitset}@ 202502L // also in \libheader{bitset} +#define @\defnlibxname{cpp_lib_hardened_deque}@ 202502L // also in \libheader{deque} +#define @\defnlibxname{cpp_lib_hardened_expected}@ 202502L // also in \libheader{expected} +#define @\defnlibxname{cpp_lib_hardened_forward_list}@ 202502L // also in \libheader{forward_list} +#define @\defnlibxname{cpp_lib_hardened_inplace_vector}@ 202502L // also in \libheader{inplace_vector} +#define @\defnlibxname{cpp_lib_hardened_list}@ 202502L // also in \libheader{list} +#define @\defnlibxname{cpp_lib_hardened_mdspan}@ 202502L // also in \libheader{mdspan} +#define @\defnlibxname{cpp_lib_hardened_optional}@ 202502L // also in \libheader{optional} +#define @\defnlibxname{cpp_lib_hardened_span}@ 202502L // also in \libheader{span} +#define @\defnlibxname{cpp_lib_hardened_valarray}@ 202502L // also in \libheader{valarray} +#define @\defnlibxname{cpp_lib_hardened_vector}@ 202502L // also in \libheader{vector} +\end{codeblock} + \pnum The macro \xname{cpp_lib_freestanding_operator_new} is defined to the integer literal \tcode{202306L} @@ -824,6 +882,11 @@ Freestanding implementations should only define a macro from \libheader{version} if the implementation provides the corresponding facility in its entirety. +\pnum +\recommended +A non-hardened implementation should not define macros from \libheader{version} +required for hardened implementations. + \rSec2[limits.syn]{Header \tcode{} synopsis} \indexheader{limits}% @@ -1012,6 +1075,11 @@ \pnum \indextext{signal-safe!\idxcode{numeric_limits} members}% Each member function defined in this subclause is signal-safe\iref{support.signal}. +\begin{note} +\indextext{LIA-1}% +The arithmetic specification described in ISO/IEC 10967-1:2012 is +commonly termed LIA-1. +\end{note} \indexlibrarymember{min}{numeric_limits}% \begin{itemdecl} @@ -1222,16 +1290,14 @@ \pnum Measure of the maximum rounding error. \begin{footnote} -Rounding error is described in -LIA-1 -Section 5.2.4 and +Rounding error is described in ISO/IEC 10967-1:2012 Section 5.2.4 and Annex C Rationale Section C.5.2.4 --- Rounding and rounding constants. \end{footnote} \end{itemdescr} \indexlibrarymember{min_exponent}{numeric_limits}% \begin{itemdecl} -static constexpr int min_exponent; +static constexpr int min_exponent; \end{itemdecl} \begin{itemdescr} @@ -1251,7 +1317,7 @@ \indexlibrarymember{min_exponent10}{numeric_limits}% \begin{itemdecl} -static constexpr int min_exponent10; +static constexpr int min_exponent10; \end{itemdecl} \begin{itemdescr} @@ -1269,7 +1335,7 @@ \indexlibrarymember{max_exponent}{numeric_limits}% \begin{itemdecl} -static constexpr int max_exponent; +static constexpr int max_exponent; \end{itemdecl} \begin{itemdescr} @@ -1289,7 +1355,7 @@ \indexlibrarymember{max_exponent10}{numeric_limits}% \begin{itemdecl} -static constexpr int max_exponent10; +static constexpr int max_exponent10; \end{itemdecl} \begin{itemdescr} @@ -1334,7 +1400,7 @@ \tcode{true} if the type has a representation for a quiet (non-signaling) ``Not a Number''. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1356,7 +1422,7 @@ \pnum \tcode{true} if the type has a representation for a signaling ``Not a Number''. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1378,7 +1444,7 @@ \pnum Representation of positive infinity, if available. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1397,7 +1463,7 @@ \pnum Representation of a quiet ``Not a Number'', if available. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1416,7 +1482,7 @@ \pnum Representation of a signaling ``Not a Number'', if available. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1436,7 +1502,7 @@ \pnum Minimum positive subnormal value, if available. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} Otherwise, minimum positive normalized value. @@ -1451,9 +1517,9 @@ \begin{itemdescr} \pnum -\tcode{true} if and only if the type adheres to ISO/IEC/IEEE 60559. +\tcode{true} if and only if the type adheres to \IsoFloatUndated{}. \begin{footnote} -ISO/IEC/IEEE 60559:2020 is the same as IEEE 754-2019. +\IsoFloatUndated{}:2020 is the same as IEEE 754-2019. \end{footnote} \begin{note} The value is \tcode{true} for any of the types @@ -1474,7 +1540,7 @@ \pnum \tcode{true} if the set of values representable by the type is finite. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \begin{note} All fundamental types\iref{basic.fundamental} are bounded. This member would be \tcode{false} for arbitrary @@ -1494,7 +1560,7 @@ \pnum \tcode{true} if the type is modulo. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} A type is modulo if, for any operation involving \tcode{+}, \tcode{-}, or \tcode{*} on values of that type whose result would fall outside the range @@ -1523,7 +1589,7 @@ if, at the start of the program, there exists a value of the type that would cause an arithmetic operation using that value to trap. \begin{footnote} -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1541,8 +1607,8 @@ if tinyness is detected before rounding. \begin{footnote} Refer to -ISO/IEC/IEEE 60559. -Required by LIA-1. +\IsoFloatUndated{}. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1559,7 +1625,7 @@ The rounding style for the type. \begin{footnote} Equivalent to \tcode{FLT_ROUNDS}. -Required by LIA-1. +Required by ISO/IEC 10967-1:2012. \end{footnote} \pnum @@ -1612,9 +1678,9 @@ static constexpr int max_exponent = +128; static constexpr int max_exponent10 = + 38; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; static constexpr float infinity() noexcept { return @\textit{value}@; } static constexpr float quiet_NaN() noexcept { return @\textit{value}@; } @@ -1869,6 +1935,34 @@ \indexlibraryglobal{uint_least64_t}% \indexlibraryglobal{uintmax_t}% \indexlibraryglobal{uintptr_t}% +\indexlibraryglobal{INTN_MIN}% +\indexlibraryglobal{INTN_MAX}% +\indexlibraryglobal{UINTN_MAX}% +\indexlibraryglobal{INT_FASTN_MIN}% +\indexlibraryglobal{INT_FASTN_MAX}% +\indexlibraryglobal{UINT_FASTN_MAX}% +\indexlibraryglobal{INT_LEASTN_MIN}% +\indexlibraryglobal{INT_LEASTN_MAX}% +\indexlibraryglobal{UINT_LEASTN_MAX}% +\indexlibraryglobal{INTMAX_MIN}% +\indexlibraryglobal{INTMAX_MAX}% +\indexlibraryglobal{UINTMAX_MAX}% +\indexlibraryglobal{INTPTR_MIN}% +\indexlibraryglobal{INTPTR_MAX}% +\indexlibraryglobal{UINTPTR_MAX}% +\indexlibraryglobal{PTRDIFF_MIN}% +\indexlibraryglobal{PTRDIFF_MAX}% +\indexlibraryglobal{SIZE_MAX}% +\indexlibraryglobal{SIG_ATOMIC_MIN}% +\indexlibraryglobal{SIG_ATOMIC_MAX}% +\indexlibraryglobal{WCHAR_MAX}% +\indexlibraryglobal{WCHAR_MIN}% +\indexlibraryglobal{WINT_MIN}% +\indexlibraryglobal{WINT_MAX}% +\indexlibraryglobal{INTN_C}% +\indexlibraryglobal{UINTN_C}% +\indexlibraryglobal{INTMAX_C}% +\indexlibraryglobal{UINTMAX_C}% \begin{codeblock} // all freestanding namespace std { @@ -2034,7 +2128,7 @@ \pnum \remarks -The program is terminated without executing destructors for objects of automatic, +The program is terminated without executing destructors for objects with automatic, thread, or static storage duration and without calling functions passed to \tcode{atexit()}\iref{basic.start.term}. \indextext{signal-safe!\idxcode{_Exit}}% @@ -2265,7 +2359,7 @@ new_handler set_new_handler(new_handler new_p) noexcept; // \ref{ptr.launder}, pointer optimization barrier - template [[nodiscard]] constexpr T* launder(T* p) noexcept; + template constexpr T* launder(T* p) noexcept; // \ref{hardware.interference}, hardware interference size inline constexpr size_t hardware_destructive_interference_size = @\impdef{}@; @@ -2273,11 +2367,10 @@ } // \ref{new.delete}, storage allocation and deallocation -[[nodiscard]] void* operator new(std::size_t size); -[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment); -[[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment, - const std::nothrow_t&) noexcept; +void* operator new(std::size_t size); +void* operator new(std::size_t size, std::align_val_t alignment); +void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; void operator delete(void* ptr) noexcept; void operator delete(void* ptr, std::size_t size) noexcept; @@ -2286,11 +2379,11 @@ void operator delete(void* ptr, const std::nothrow_t&) noexcept; void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new[](std::size_t size); -[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment); -[[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment, - const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size); +void* operator new[](std::size_t size, std::align_val_t alignment); +void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; void operator delete[](void* ptr) noexcept; void operator delete[](void* ptr, std::size_t size) noexcept; @@ -2299,8 +2392,8 @@ void operator delete[](void* ptr, const std::nothrow_t&) noexcept; void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new (std::size_t size, void* ptr) noexcept; -[[nodiscard]] void* operator new[](std::size_t size, void* ptr) noexcept; +constexpr void* operator new (std::size_t size, void* ptr) noexcept; +constexpr void* operator new[](std::size_t size, void* ptr) noexcept; void operator delete (void* ptr, void*) noexcept; void operator delete[](void* ptr, void*) noexcept; \end{codeblock} @@ -2337,18 +2430,12 @@ If any of the default versions of the replaceable global allocation functions meet the requirements of a hosted implementation, they all should. -\newcommand{\replaceabledesc}[1]{% -A \Cpp{} program may define functions with #1 of these function signatures, -and thereby displace the default versions defined by the -\Cpp{} standard library.% -} - \rSec3[new.delete.single]{Single-object forms} \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new(std::size_t size); -[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment); +void* operator new(std::size_t size); +void* operator new(std::size_t size, std::align_val_t alignment); \end{itemdecl} \begin{itemdescr} @@ -2363,10 +2450,6 @@ The second form is called for a type with new-extended alignment, and the first form is called otherwise. -\pnum -\replaceable -\replaceabledesc{either} - \pnum \required Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic}, @@ -2403,13 +2486,16 @@ \tcode{new_handler} function does not return. \end{itemize} + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment, - const std::nothrow_t&) noexcept; +void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2422,10 +2508,6 @@ \tcode{bad_alloc} exception. -\pnum -\replaceable -\replaceabledesc{either} - \pnum \required Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic}, @@ -2453,6 +2535,10 @@ T* p2 = new(nothrow) T; // returns \keyword{nullptr} if it fails \end{codeblock} \end{example} + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \indexlibrarymember{delete}{operator}% @@ -2495,20 +2581,6 @@ \grammarterm{delete-expression}\iref{expr.delete} to render the value of \tcode{ptr} invalid. -\pnum -\replaceable -\replaceabledesc{any} -If a function without a \tcode{size} parameter is defined, -the program should also define -the corresponding function with a \tcode{size} parameter. -If a function with a \tcode{size} parameter is defined, -the program shall also define -the corresponding version without the \tcode{size} parameter. -\begin{note} -The default behavior below might change in the future, which will require -replacing both deallocation functions when replacing the allocation function. -\end{note} - \pnum \required A call to an \tcode{operator delete} @@ -2529,7 +2601,7 @@ forward their other parameters to the corresponding function without a \tcode{size} parameter. \begin{note} -See the note in the above \replaceable paragraph. +See the note in the below \remarks paragraph. \end{note} \pnum @@ -2551,6 +2623,22 @@ or \tcode{realloc}, declared in \libheaderref{cstdlib}. +This function is replaceable\iref{dcl.fct.def.replace}. +If a replacement function +without a \tcode{size} parameter +is defined by the program, +the program should also define the corresponding +function with a \tcode{size} parameter. +If a replacement function +with a \tcode{size} parameter +is defined by the program, +the program shall also define the corresponding +version without the \tcode{size} parameter. +\begin{note} +The default behavior above might change in the future, +which will require replacing both deallocation functions +when replacing the allocation function. +\end{note} \end{itemdescr} \indexlibrarymember{delete}{operator}% @@ -2589,23 +2677,23 @@ when the constructor invoked from a nothrow placement version of the \grammarterm{new-expression} throws an exception. -\pnum -\replaceable -\replaceabledesc{either} - \pnum \default Calls \tcode{operator delete(ptr)}, or \tcode{operator delete(ptr, alignment)}, respectively. + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \rSec3[new.delete.array]{Array forms} \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new[](std::size_t size); -[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment); +void* operator new[](std::size_t size); +void* operator new[](std::size_t size, std::align_val_t alignment); \end{itemdecl} \begin{itemdescr} @@ -2637,10 +2725,6 @@ to obtain space to store supplemental information. \end{footnote} -\pnum -\replaceable -\replaceabledesc{either} - \pnum \required Same as for @@ -2654,13 +2738,16 @@ or \tcode{operator new(size, alignment)}, respectively. + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; -[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment, - const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2673,10 +2760,6 @@ \tcode{bad_alloc} exception. -\pnum -\replaceable -\replaceabledesc{either} - \pnum \required Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic}, @@ -2696,6 +2779,10 @@ If the call returns normally, returns the result of that call. Otherwise, returns a null pointer. + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \indexlibrarymember{delete}{operator}% @@ -2738,20 +2825,6 @@ \grammarterm{delete-expression} to render the value of \tcode{ptr} invalid. -\pnum -\replaceable -\replaceabledesc{any} -If a function without a \tcode{size} parameter is defined, -the program should also define -the corresponding function with a \tcode{size} parameter. -If a function with a \tcode{size} parameter is defined, -the program shall also define -the corresponding version without the \tcode{size} parameter. -\begin{note} -The default behavior below might change in the future, which will require -replacing both deallocation functions when replacing the allocation function. -\end{note} - \pnum \required A call to an \tcode{operator delete[]} @@ -2774,6 +2847,25 @@ The functions that do not have a \tcode{size} parameter forward their parameters to the corresponding \tcode{operator delete} (single-object) function. + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. +If a replacement function +without a \tcode{size} parameter +is defined by the program, +the program should also define the corresponding +function with a \tcode{size} parameter. +If a replacement function +with a \tcode{size} parameter +is defined by the program, +the program shall also define the corresponding +version without the \tcode{size} parameter. +\begin{note} +The default behavior above might change in the future, +which will require replacing both deallocation functions +when replacing the allocation function. +\end{note} \end{itemdescr} \indexlibrarymember{delete}{operator}% @@ -2812,15 +2904,15 @@ when the constructor invoked from a nothrow placement version of the array \grammarterm{new-expression} throws an exception. -\pnum -\replaceable -\replaceabledesc{either} - \pnum \default Calls \tcode{operator delete[](ptr)}, or \tcode{operator delete[](ptr, alignment)}, respectively. + +\pnum +\remarks +This function is replaceable\iref{dcl.fct.def.replace}. \end{itemdescr} \rSec3[new.delete.placement]{Non-allocating forms} @@ -2833,7 +2925,7 @@ \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new(std::size_t size, void* ptr) noexcept; +constexpr void* operator new(std::size_t size, void* ptr) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2858,7 +2950,7 @@ \indexlibrarymember{new}{operator}% \begin{itemdecl} -[[nodiscard]] void* operator new[](std::size_t size, void* ptr) noexcept; +constexpr void* operator new[](std::size_t size, void* ptr) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2935,7 +3027,7 @@ class bad_alloc : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -2948,7 +3040,7 @@ \indexlibrarymember{what}{bad_alloc}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -2966,7 +3058,7 @@ class bad_array_new_length : public bad_alloc { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -2979,7 +3071,7 @@ \indexlibrarymember{what}{bad_array_new_length}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -3065,7 +3157,7 @@ \indexlibraryglobal{launder}% \begin{itemdecl} -template [[nodiscard]] constexpr T* launder(T* p) noexcept; +template constexpr T* launder(T* p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3174,12 +3266,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}% @@ -3205,8 +3301,8 @@ size_t hash_code() const noexcept; const char* name() const noexcept; - type_info(const type_info&) = delete; // cannot be copied - type_info& operator=(const type_info&) = delete; // cannot be copied + type_info(const type_info&) = delete; + type_info& operator=(const type_info&) = delete; }; } \end{codeblock} @@ -3300,7 +3396,7 @@ class bad_cast : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -3316,7 +3412,7 @@ \indexlibrarymember{what}{bad_cast}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -3334,7 +3430,7 @@ class bad_typeid : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -3350,7 +3446,7 @@ \indexlibrarymember{what}{bad_typeid}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -3359,6 +3455,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} @@ -3495,7 +3751,7 @@ \pnum \remarks Any call to \tcode{current} that appears -as a default member initializer\iref{class.mem}, or +as a default member initializer\iref{class.mem.general}, or as a subexpression thereof, should correspond to the location of the constructor definition or aggregate initialization @@ -3605,16 +3861,16 @@ terminate_handler set_terminate(terminate_handler f) noexcept; [[noreturn]] void terminate() noexcept; - int uncaught_exceptions() noexcept; + constexpr int uncaught_exceptions() noexcept; using exception_ptr = @\unspec@; - exception_ptr current_exception() noexcept; - [[noreturn]] void rethrow_exception(exception_ptr p); - template exception_ptr make_exception_ptr(E e) noexcept; + constexpr exception_ptr current_exception() noexcept; + [[noreturn]] constexpr void rethrow_exception(exception_ptr p); + template constexpr exception_ptr make_exception_ptr(E e) noexcept; - template [[noreturn]] void throw_with_nested(T&& t); - template void rethrow_if_nested(const E& e); + template [[noreturn]] constexpr void throw_with_nested(T&& t); + template constexpr void rethrow_if_nested(const E& e); } \end{codeblock} @@ -3626,11 +3882,11 @@ namespace std { class exception { public: - exception() noexcept; - exception(const exception&) noexcept; - exception& operator=(const exception&) noexcept; - virtual ~exception(); - virtual const char* what() const noexcept; + constexpr exception() noexcept; + constexpr exception(const exception&) noexcept; + constexpr exception& operator=(const exception&) noexcept; + constexpr virtual ~exception(); + constexpr virtual const char* what() const noexcept; }; } \end{codeblock} @@ -3663,8 +3919,8 @@ \indexlibraryctor{exception}% \indexlibrarymember{operator=}{exception}% \begin{itemdecl} -exception(const exception& rhs) noexcept; -exception& operator=(const exception& rhs) noexcept; +constexpr exception(const exception& rhs) noexcept; +constexpr exception& operator=(const exception& rhs) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3676,7 +3932,7 @@ \indexlibrarydtor{exception}% \begin{itemdecl} -virtual ~exception(); +constexpr virtual ~exception(); \end{itemdecl} \begin{itemdescr} @@ -3688,13 +3944,15 @@ \indexlibrarymember{what}{exception}% \begin{itemdecl} -virtual const char* what() const noexcept; +constexpr virtual const char* what() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{exception::what}} \ntbs{}. +An \impldef{return value of \tcode{exception::what}} \ntbs{}, +which during constant evaluation is encoded with +the ordinary literal encoding\iref{lex.ccon}. \pnum \remarks @@ -3715,7 +3973,7 @@ class bad_exception : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -3730,7 +3988,7 @@ \indexlibrarymember{what}{bad_exception}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -3837,13 +4095,13 @@ \indexlibraryglobal{uncaught_exceptions}% \begin{itemdecl} -int uncaught_exceptions() noexcept; +constexpr int uncaught_exceptions() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -The number of uncaught exceptions\iref{except.uncaught}. +The number of uncaught exceptions\iref{except.throw} in the current thread. \pnum \remarks @@ -3898,11 +4156,14 @@ Changes in the number of \tcode{exception_ptr} objects that refer to a particular exception do not introduce a data race. \end{note} + +\pnum +All member functions are marked \tcode{constexpr}. \end{itemdescr} \indexlibraryglobal{current_exception}% \begin{itemdecl} -exception_ptr current_exception() noexcept; +constexpr exception_ptr current_exception() noexcept; \end{itemdecl} \begin{itemdescr} @@ -3933,7 +4194,7 @@ \indexlibraryglobal{rethrow_exception}% \begin{itemdecl} -[[noreturn]] void rethrow_exception(exception_ptr p); +[[noreturn]] constexpr void rethrow_exception(exception_ptr p); \end{itemdecl} \begin{itemdescr} @@ -3961,7 +4222,7 @@ \indexlibraryglobal{make_exception_ptr}% \begin{itemdecl} -template exception_ptr make_exception_ptr(E e) noexcept; +template constexpr exception_ptr make_exception_ptr(E e) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3990,18 +4251,18 @@ namespace std { class nested_exception { public: - nested_exception() noexcept; - nested_exception(const nested_exception&) noexcept = default; - nested_exception& operator=(const nested_exception&) noexcept = default; - virtual ~nested_exception() = default; + constexpr nested_exception() noexcept; + constexpr nested_exception(const nested_exception&) noexcept = default; + constexpr nested_exception& operator=(const nested_exception&) noexcept = default; + constexpr virtual ~nested_exception() = default; // access functions - [[noreturn]] void rethrow_nested() const; - exception_ptr nested_ptr() const noexcept; + [[noreturn]] constexpr void rethrow_nested() const; + constexpr exception_ptr nested_ptr() const noexcept; }; - template [[noreturn]] void throw_with_nested(T&& t); - template void rethrow_if_nested(const E& e); + template [[noreturn]] constexpr void throw_with_nested(T&& t); + template constexpr void rethrow_if_nested(const E& e); } \end{codeblock} @@ -4018,7 +4279,7 @@ \indexlibraryctor{nested_exception}% \begin{itemdecl} -nested_exception() noexcept; +constexpr nested_exception() noexcept; \end{itemdecl} \begin{itemdescr} @@ -4029,7 +4290,7 @@ \indexlibrarymember{rethrow_nested}{nested_exception}% \begin{itemdecl} -[[noreturn]] void rethrow_nested() const; +[[noreturn]] constexpr void rethrow_nested() const; \end{itemdecl} \begin{itemdescr} @@ -4041,7 +4302,7 @@ \indexlibrarymember{nested_ptr}{nested_exception}% \begin{itemdecl} -exception_ptr nested_ptr() const noexcept; +constexpr exception_ptr nested_ptr() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4052,7 +4313,7 @@ \indexlibrarymember{throw_with_nested}{nested_exception}% \begin{itemdecl} -template [[noreturn]] void throw_with_nested(T&& t); +template [[noreturn]] constexpr void throw_with_nested(T&& t); \end{itemdecl} \begin{itemdescr} @@ -4075,7 +4336,7 @@ \indexlibrarymember{rethrow_if_nested}{nested_exception}% \begin{itemdecl} -template void rethrow_if_nested(const E& e); +template constexpr void rethrow_if_nested(const E& e); \end{itemdecl} \begin{itemdescr} @@ -4091,6 +4352,268 @@ \end{codeblock} \end{itemdescr} +\rSec1[support.contract]{Contract-violation handling} + +\rSec2[contracts.syn]{Header \tcode{} synopsis} + +\pnum +The header \libheader{contracts} defines types +for reporting information about contract violations\iref{basic.contract.eval}. + +\indexheader{contracts} +\indexlibraryglobal{contract_violation}% +\begin{codeblock} +// all freestanding +namespace std::contracts { + + enum class assertion_kind : @\unspec@ { + pre = 1, + post = 2, + assert = 3 + }; + + enum class evaluation_semantic : @\unspec@ { + ignore = 1, + observe = 2, + enforce = 3, + quick_enforce = 4 + }; + + enum class detection_mode : @\unspec@ { + predicate_false = 1, + evaluation_exception = 2 + }; + + class contract_violation { + // no user-accessible constructor + public: + contract_violation(const contract_violation&) = delete; + contract_violation& operator=(const contract_violation&) = delete; + + @\seebelow@ ~contract_violation(); + + const char* comment() const noexcept; + contracts::detection_mode detection_mode() const noexcept; + exception_ptr evaluation_exception() const noexcept; + bool is_terminating() const noexcept; + assertion_kind kind() const noexcept; + source_location location() const noexcept; + evaluation_semantic semantic() const noexcept; + }; + + void invoke_default_contract_violation_handler(const contract_violation&); +} +\end{codeblock} + +\rSec2[support.contract.enum]{Enumerations} + +\pnum +\recommended +For all enumerations in \ref{support.contract.enum}, +if implementation-defined enumerators are provided, +they should have a minimum value of $1000$. + +\pnum +The enumerators of \tcode{assertion_kind} +correspond to +the syntactic forms of a contract assertion\iref{basic.contract.general}, +with meanings listed in Table~\ref{tab:support.contract.enum.kind}. + +\begin{floattable}{Enum \tcode{assertion_kind}}{support.contract.enum.kind} +{ll} +\topline +\lhdr{Name} & \rhdr{Meaning} \\ \capsep +\tcode{pre} & A precondition assertion \\ \rowsep +\tcode{post} & A postcondition assertion \\ \rowsep +\tcode{assert} & An \grammarterm{assertion-statement} \\ \rowsep +\end{floattable} + +\pnum +The enumerators of \tcode{evaluation_semantic} +correspond to +the evaluation semantics with which +a contract assertion may be evaluated\iref{basic.contract.eval}, +with meanings listed in Table~\ref{tab:support.contract.enum.semantic}. + +\begin{floattable}{Enum \tcode{evaluation_semantic}}{support.contract.enum.semantic} +{ll} +\topline +\lhdr{Name} & \rhdr{Meaning} \\ \capsep +\tcode{ignore} & Ignore evaluation semantic \\ \rowsep +\tcode{observe} & Observe evaluation semantic \\ \rowsep +\tcode{enforce} & Enforce evaluation semantic \\ \rowsep +\tcode{quick_enforce} & Quick-enforce evaluation semantic \\ \rowsep +\end{floattable} + +\pnum +The enumerators of \tcode{detection_mode} correspond to the manners in which a +contract violation can be identified\iref{basic.contract.eval}, with +meanings listed in \mbox{Table~\ref{tab:support.contract.enum.detection}}. + +\begin{floattable}{Enum \tcode{detection_mode}}{support.contract.enum.detection} +{lp{.6\hsize}} +\topline +\lhdr{Name} & \rhdr{Meaning} \\ \capsep +\tcode{predicate_false} & The predicate of the contract assertion evaluated to \keyword{false} or would have evaluated to \keyword{false}. \\ \rowsep +\tcode{evaluation_exception} & An uncaught exception occurred during evaluation of the contract assertion. \\ \rowsep +\end{floattable} + +\rSec2[support.contract.violation]{Class \tcode{contract_violation}} + +\pnum +\indexlibraryglobal{contract_violation}% +The class \tcode{contract_violation} +defines the type of objects used to represent +a contract violation that has been detected +during the evaluation of a contract assertion +with a particular evaluation semantic\iref{basic.contract.eval}. +Objects of this type can +be created only by the implementation. +It is +\impldef{whether \tcode{contract_violation} has a virtual destructor} +whether the destructor is virtual. + +\begin{itemdecl} +const char* comment() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An +\impldef{the contents provided in the \tcode{comment} field of \tcode{contract_violation}} +\ntmbs{} in +the ordinary literal encoding\iref{lex.charset}. + +\pnum +\recommended +The string returned +should contain a textual representation +of the predicate of the violated contract assertion +or an empty string if +storing a textual representation is undesired. +\begin{note} +The string can represent a +truncated, reformatted, or summarized rendering of the +predicate, before or after preprocessing. +\end{note} + +\end{itemdescr} + +\begin{itemdecl} +contracts::detection_mode detection_mode() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The enumerator value +corresponding to +the manner in which the contract violation was identified. + +\end{itemdescr} + +\begin{itemdecl} +exception_ptr evaluation_exception() const noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\returns +If the contract violation occurred +because the evaluation of the predicate exited via an exception, +an \tcode{exception_ptr} object that refers to +that exception or a copy of that exception; +otherwise, a null \tcode{exception_ptr} object. + +\end{itemdescr} + +\begin{itemdecl} +bool is_terminating() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\indextext{contract evaluation semantics!terminating}% +\pnum +\returns +\keyword{true} if the evaluation semantic is +a terminating semantic\iref{basic.contract.eval}; +otherwise, \tcode{false}. + +\end{itemdescr} + +\begin{itemdecl} +assertion_kind kind() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The enumerator value +corresponding to +the syntactic form of the violated contract assertion. + +\end{itemdescr} + +\begin{itemdecl} +source_location location() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{source_location} object +with +\impldef{the contents provided in the \tcode{location} field of \tcode{contract_violation}} +value. + +\pnum +\recommended +The value returned should be +a default constructed \tcode{source_location} object +or a value identifying the violated contract assertion: +\begin{itemize} +\item +When possible, +if the violated contract assertion was a precondition, +the source location of the function invocation should be returned. +\item +Otherwise, +the source location of the contract assertion should be returned. +\end{itemize} + +\end{itemdescr} + +\begin{itemdecl} +evaluation_semantic semantic() const noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\returns +The enumerator value +corresponding to +the evaluation semantic with which +the violated contract assertion was evaluated. + +\end{itemdescr} + +\rSec2[support.contract.invoke]{Invoke default handler} + +\begin{itemdecl} +void invoke_default_contract_violation_handler(const contract_violation& v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invokes the default contract-violation handler\iref{basic.contract.handler} +with the argument \tcode{v}. + +\end{itemdescr} + \rSec1[support.initlist]{Initializer lists} \rSec2[support.initlist.general]{General} @@ -4139,7 +4662,7 @@ A pair of pointers or a pointer plus a length would be obvious representations for \tcode{initializer_list}. \tcode{initializer_list} is used to implement initializer lists as specified -in~\ref{dcl.init.list}. Copying an initializer list does not copy the underlying +in~\ref{dcl.init.list}. Copying an \tcode{initializer_list} does not copy the underlying elements. \end{note} @@ -4332,7 +4855,7 @@ an argument other than a literal \tcode{0} is undefined. \pnum -For the purposes of subclause \ref{cmp.categories}, +For the purposes of \ref{cmp.categories}, \defn{substitutability} is the property that \tcode{f(a) == f(b)} is \tcode{true} whenever \tcode{a == b} is \tcode{true}, where \tcode{f} denotes a function that reads only comparison-salient state @@ -4784,7 +5307,7 @@ lvalues of types \tcode{const remove_reference_t} and \tcode{const remove_reference_t}, respectively. \tcode{T} and \tcode{U} model -\tcode{\exposconcept{partially-ordered-with}} only if: +\tcode{\exposconcept{partially-ordered-with}} only if \begin{itemize} \item \tcode{t < u}, @@ -4795,7 +5318,7 @@ \tcode{u <= t}, \tcode{u > t}, and \tcode{u >= t} - have the same domain. + have the same domain, \item \tcode{bool(t < u) == bool(u > t)} is \tcode{true}, \item @@ -4820,7 +5343,7 @@ Let \tcode{a} and \tcode{b} be lvalues of type \tcode{const remove_reference_t}. \tcode{T} and \tcode{Cat} -model \tcode{\libconcept{three_way_comparable}} only if: +model \tcode{\libconcept{three_way_comparable}} only if \begin{itemize} \item \tcode{(a <=> b == 0) == bool(a == b)} is \tcode{true}, @@ -4870,7 +5393,7 @@ Let \tcode{\exposid{CONVERT_TO_LVALUE}(E)} be defined as in \ref{concepts.compare.general}. \tcode{T}, \tcode{U}, and \tcode{Cat} -model \tcode{\libconcept{three_way_comparable_with}} only if: +model \tcode{\libconcept{three_way_comparable_with}} only if \begin{itemize} \item \tcode{t <=> u} and \tcode{u <=> t} have the same domain, @@ -4942,7 +5465,7 @@ observed by \tcode{T}'s comparison operators, and if \tcode{numeric_limits::is_iec559} is \tcode{true}, is additionally consistent with the \tcode{totalOrder} operation - as specified in ISO/IEC/IEEE 60559. + as specified in \IsoFloatUndated{}. \item Otherwise, \tcode{strong_ordering(compare_three_way()(E, F))} if it is a well-formed expression. @@ -5125,7 +5648,8 @@ Otherwise, if the expressions \tcode{E == F}, \tcode{E < F}, and \tcode{F < E} are all well-formed and - each of \tcode{decltype(E == F)} and \tcode{decltype(E < F)} models + each of \tcode{decltype(E == F)}, \tcode{decltype(E < F)}, and + \tcode{decltype(F < E)} models \exposconcept{boolean-testable}, \begin{codeblock} E == F ? partial_ordering::equivalent : @@ -5566,6 +6090,8 @@ \rSec3[coroutine.handle.noop]{Class \tcode{coroutine_handle}} +\rSec4[coroutine.handle.noop.general]{General} + \indexlibraryglobal{coroutine_handle}% \begin{codeblock} namespace std { @@ -5780,21 +6306,16 @@ \rSec2[cstdarg.syn]{Header \tcode{} synopsis} \indexheader{cstdarg}% -\indexlibraryglobal{va_list}% -\indexlibraryglobal{va_start}% -\indexlibraryglobal{va_copy}% -\indexlibraryglobal{va_end}% -\indexlibraryglobal{va_arg}% \begin{codeblock} // all freestanding namespace std { - using va_list = @\seebelow@; + using @\libglobal{va_list}@ = @\seebelow@; } -#define va_arg(V, P) @\seebelow@ -#define va_copy(VDST, VSRC) @\seebelow@ -#define va_end(V) @\seebelow@ -#define va_start(V, P) @\seebelow@ +#define @\libmacro{va_arg}@(V, P) @\seebelow@ +#define @\libmacro{va_copy}@(VDST, VSRC) @\seebelow@ +#define @\libmacro{va_end}@(V) @\seebelow@ +#define @\libmacro{va_start}@(V, P) @\seebelow@ \end{codeblock} \pnum @@ -5802,12 +6323,11 @@ standard library header \libheader{stdarg.h}, with the following changes: \begin{itemize} \item -In lieu of the default argument promotions specified in ISO C 6.5.2.2, +In lieu of the default argument promotions specified in \IsoC{} 6.5.2.2, the definition in~\ref{expr.call} applies. \item -The restrictions that ISO C places on the second parameter to the -\indexlibraryglobal{va_start}% -\tcode{va_start} macro in header \libheader{stdarg.h} +The restrictions that C places on the second parameter to the +\libmacro{va_start} macro in header \libheader{stdarg.h} are different in this document. The parameter \tcode{parmN} @@ -5999,8 +6519,8 @@ the \defnx{C headers}{headers!C library} shown in \tref{c.headers}. The intended use of these headers is for interoperability only. It is possible that \Cpp{} source files need to include -one of these headers in order to be valid ISO C. -Source files that are not intended to also be valid ISO C +one of these headers in order to be valid C. +Source files that are not intended to also be valid C should not use any of the C headers. \begin{note} @@ -6011,7 +6531,7 @@ assuredly defines them in namespace \tcode{std}. \end{note} \begin{example} -The following source file is both valid \Cpp{} and valid ISO C. +The following source file is both valid \Cpp{} and valid C. Viewed as \Cpp{}, it declares a function with C language linkage; viewed as C it simply declares a function (and provides a prototype). \begin{codeblock} @@ -6045,16 +6565,18 @@ \libheader{stdalign.h} \\ \libheaderdef{stdarg.h} \\ \libheader{stdatomic.h} \\ +\libheader{stdbit.h} \\ \libheader{stdbool.h} \\ -\libheaderdef{stddef.h} \\ \columnbreak +\libheader{stdckdint.h} \\ +\libheaderdef{stddef.h} \\ \libheaderdef{stdint.h} \\ \libheaderdef{stdio.h} \\ \libheaderdef{stdlib.h} \\ \libheaderdef{string.h} \\ +\columnbreak \libheader{tgmath.h} \\ \libheaderdef{time.h} \\ -\columnbreak \libheaderdef{uchar.h} \\ \libheaderdef{wchar.h} \\ \libheaderdef{wctype.h} \\ @@ -6112,7 +6634,6 @@ \rSec2[stdbool.h.syn]{Header \tcode{} synopsis} \indexheader{stdbool.h}% -\indexhdr{stdbool.h}% \pnum The contents of the \Cpp{} header \libheader{stdbool.h} are the same as the C standard library header \libheader{stdbool.h}, with the following changes: @@ -6158,7 +6679,9 @@ \libheaderref{iso646.h}, \libheaderref{stdalign.h},\newline \libheaderref{stdatomic.h}, -\libheaderref{stdbool.h}, and +\libheaderref{stdbit.h}, +\libheaderref{stdbool.h}, +\libheaderref{stdckdint.h}, and\newline \libheaderref{tgmath.h}, each of which has a name of the form diff --git a/source/tables.tex b/source/tables.tex index c1f20586f0..678ec5d98b 100644 --- a/source/tables.tex +++ b/source/tables.tex @@ -48,6 +48,7 @@ % floattablebase without TableBase, used for lib2dtab2base \newenvironment{floattablebasex}[4] { + \protect\hypertarget{tab:#2}{} \begin{table}[#4] \caption{\label{tab:#2}#1 \quad [tab:#2]} \begin{center} @@ -196,6 +197,7 @@ \newenvironment{LongTable}[3] { \newcommand{\continuedcaption}{\caption[]{#1 (continued)}} + \protect\hypertarget{tab:#2}{} \begin{TableBase} \begin{longtable}{|#3|} \caption{#1 \quad [tab:#2]}\label{tab:#2} @@ -490,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 3d27393946..bf283e46da 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -143,12 +143,26 @@ \begin{note} A template cannot have the same name as any other name bound in the same scope\iref{basic.scope.scope}, except -that a function template can share a name with non-template -functions\iref{dcl.fct} and/or function templates\iref{temp.over}. +that a function template can share a name with \grammarterm{using-declarator}s, +a type, non-template functions\iref{dcl.fct} and/or function templates\iref{temp.over}. Specializations, including partial specializations\iref{temp.spec.partial}, do not reintroduce or bind names. Their target scope is the target scope of the primary template, so all specializations of a template belong to the same scope as it does. +\begin{example} +\begin{codeblock} +void f() {} +class f {}; // OK +namespace N { + void f(int) {} +} +using N::f; // OK +template void f(long) {} // \#1, OK +template void f(long) {} // error: redefinition of \#1 +template void f(long long) {} // OK +template<> void f(long long) {} // OK, doesn't bind a name +\end{codeblock} +\end{example} \end{note} \pnum @@ -223,7 +237,10 @@ \begin{bnf} \nontermdef{template-parameter}\br type-parameter\br - parameter-declaration + parameter-declaration\br + type-tt-parameter\br + variable-tt-parameter\br + concept-tt-parameter \end{bnf} \begin{bnf} @@ -231,9 +248,7 @@ type-parameter-key \opt{\terminal{...}} \opt{identifier}\br type-parameter-key \opt{identifier} \terminal{=} type-id\br type-constraint \opt{\terminal{...}} \opt{identifier}\br - type-constraint \opt{identifier} \terminal{=} type-id\br - template-head type-parameter-key \opt{\terminal{...}} \opt{identifier}\br - template-head type-parameter-key \opt{identifier} \terminal{=} id-expression + type-constraint \opt{identifier} \terminal{=} type-id \end{bnf} \begin{bnf} @@ -248,6 +263,30 @@ \opt{nested-name-specifier} concept-name \terminal{<} \opt{template-argument-list} \terminal{>} \end{bnf} +\begin{bnf} +\nontermdef{type-tt-parameter}\br + template-head type-parameter-key \opt{\terminal{...}} \opt{identifier}\br + template-head type-parameter-key \opt{identifier} type-tt-parameter-default +\end{bnf} + +\begin{bnf} +\nontermdef{type-tt-parameter-default}\br + \terminal{=} \opt{nested-name-specifier} template-name\br + \terminal{=} nested-name-specifier \terminal{template} template-name +\end{bnf} + +\begin{bnf} +\nontermdef{variable-tt-parameter}\br + template-head \terminal{auto} \opt{\terminal{...}} \opt{identifier}\br + template-head \terminal{auto} \opt{identifier} \terminal{=} \opt{nested-name-specifier} template-name +\end{bnf} + +\begin{bnf} +\nontermdef{concept-tt-parameter}\br + \terminal{template} \terminal{<} template-parameter-list \terminal{>} \terminal{concept} \opt{\terminal{...}} \opt{identifier}\br + \terminal{template} \terminal{<} template-parameter-list \terminal{>} \terminal{concept} \opt{identifier} \terminal{=} \opt{nested-name-specifier} template-name +\end{bnf} + \indextext{component name}% The component names of a \grammarterm{type-constraint} are its \grammarterm{concept-name} and @@ -255,12 +294,81 @@ \begin{note} The \tcode{>} token following the \grammarterm{template-parameter-list} of a -\grammarterm{type-parameter} +\grammarterm{type-tt-parameter}, +\grammarterm{variable-tt-parameter}, or +\grammarterm{concept-tt-parameter} can be the product of replacing a \tcode{>>} token by two consecutive \tcode{>} tokens\iref{temp.names}. \end{note} +\pnum +%FIXME: "is" or "shall be"? i.e., what if it's not? +%FIXME: Note: we don't appear to ever define what a "template parameter" is; +%FIXME: is this supposed to be the definition for template parameter? +A template parameter is of one of the following kinds: +\begin{itemize} +\item +A \defnadj{type}{template parameter} is +a template parameter introduced by a \grammarterm{type-parameter}. +\item +A \defnadj{constant}{template parameter} is +a template parameter introduced by a \grammarterm{parameter-declaration}. +\item +A \defnadj{type template}{template parameter} is +a template parameter introduced by a \grammarterm{type-tt-parameter}. +\item +A \defnadj{variable template}{template parameter} is +a template parameter introduced by a \grammarterm{variable-tt-parameter}. +\item +A \defnadj{concept}{template parameter} is +a template parameter introduced by a \grammarterm{concept-tt-parameter}. +\end{itemize} + +\pnum +Type template template parameters, +variable template template parameters, and +concept template parameters +are collectively referred to as \defnadj{template}{template parameters}. + +\pnum +A concept template parameter shall not have +associated constraints\iref{temp.constr.decl}. + +\pnum +If a \grammarterm{template-parameter} is +a \grammarterm{parameter-declaration} that declares a pack\iref{dcl.fct}, or +otherwise has an ellipsis prior to its optional \grammarterm{identifier}, +then the \grammarterm{template-parameter} +declares a template parameter pack\iref{temp.variadic}. +A template parameter pack that is a \grammarterm{parameter-declaration} whose type +contains one or more unexpanded packs is a pack expansion. Similarly, +a template parameter pack that is a template template parameter with a +\grammarterm{template-parameter-list} containing one or more unexpanded +packs is a pack expansion. +A type parameter pack with a \grammarterm{type-constraint} that +contains an unexpanded parameter pack is a pack expansion. +A template parameter pack that is a pack +expansion shall not expand a template parameter pack declared in the same +\grammarterm{template-parameter-list}. +\begin{example} +\begin{codeblock} +template // \tcode{Types} is a template type parameter pack + class Tuple; // but not a pack expansion + +template // \tcode{Dims} is a constant template parameter pack + struct multi_array; // but not a pack expansion + +template + struct value_holder { + template struct apply { }; // \tcode{Values} is a constant template parameter pack + }; // and a pack expansion + +template // error: \tcode{Values} expands template type parameter + struct static_array; // pack \tcode{T} within the same template parameter list +\end{codeblock} +\end{example} + \pnum There is no semantic difference between \keyword{class} @@ -275,18 +383,7 @@ \keyword{typename} followed by a \grammarterm{qualified-id} -denotes the type in a non-type -\begin{footnote} -Since template -\grammarterm{template-parameter}{s} -and template -\grammarterm{template-argument}{s} -are treated as types for descriptive purposes, the terms -\term{non-type parameter} -and -\term{non-type argument} -are used to refer to non-type, non-template parameters and arguments. -\end{footnote} +denotes the type in a \grammarterm{parameter-declaration}. A \grammarterm{template-parameter} of the form \keyword{class} \grammarterm{identifier} is a \grammarterm{type-parameter}. @@ -296,56 +393,44 @@ int i; template void f(T t) { - T t1 = i; // template-parameters \tcode{T} and \tcode{i} + T t1 = i; // template parameters \tcode{T} and \tcode{i} ::T t2 = ::i; // global namespace members \tcode{T} and \tcode{i} } \end{codeblock} -Here, the template \tcode{f} has a \grammarterm{type-parameter} -called \tcode{T}, rather than an unnamed non-type -\grammarterm{template-parameter} of class \tcode{T}. +Here, the template \tcode{f} has a type template parameter +called \tcode{T}, rather than an unnamed constant +template parameter of class \tcode{T}. \end{example} -A \grammarterm{template-parameter} declaration shall not -have a \grammarterm{storage-class-specifier}. -Types shall not be defined in a \grammarterm{template-parameter} +The \grammarterm{parameter-declaration} of a \grammarterm{template-parameter} +shall not have a \grammarterm{storage-class-specifier}. +Types shall not be defined in a template parameter declaration. \pnum -The \grammarterm{identifier} in a \grammarterm{type-parameter} is not looked up. -A \grammarterm{type-parameter} -whose \grammarterm{identifier} does not follow an ellipsis -defines its -\grammarterm{identifier} -to be a -\grammarterm{typedef-name} -(if declared without -\keyword{template}) -or -\grammarterm{template-name} -(if declared with -\keyword{template}) +The \grammarterm{identifier} in +a \grammarterm{template-parameter} denoting a type or template +is not looked up. +An \grammarterm{identifier} that does not follow an ellipsis +is defined to be +\begin{itemize} +\item +a \grammarterm{typedef-name} for a \grammarterm{type-parameter}, +\item +a \grammarterm{template-name} for a \grammarterm{variable-tt-parameter}, +\item +a \grammarterm{template-name} for a \grammarterm{type-tt-parameter}, or +\item +a \grammarterm{concept-name} for a \grammarterm{concept-tt-parameter}, +\end{itemize} in the scope of the template declaration. -\begin{note} -A template argument can be a class template or alias template. -For example, - -\begin{codeblock} -template class myarray { @\commentellip@ }; - -template class C = myarray> -class Map { - C key; - C value; -}; -\end{codeblock} -\end{note} \pnum A \grammarterm{type-constraint} \tcode{Q} that designates a concept \tcode{C} can be used to constrain a contextually-determined type or template type parameter pack \tcode{T} with a \grammarterm{constraint-expression} \tcode{E} defined as follows. -If \tcode{Q} is of the form \tcode{C}, -then let \tcode{E$'$} be \tcode{C}. +If \tcode{Q} is of the form \tcode{C}, +then let \tcode{E$'$} be \tcode{C}. Otherwise, let \tcode{E$'$} be \tcode{C}. If \tcode{T} is not a pack, then \tcode{E} is \tcode{E$'$}, @@ -375,7 +460,7 @@ \end{example} \pnum -A non-type \grammarterm{template-parameter} +A constant template parameter shall have one of the following (possibly cv-qualified) types: \begin{itemize} \item a structural type (see below), @@ -399,24 +484,24 @@ \item all base classes and non-static data members are public and non-mutable and \item -the types of all bases classes and non-static data members are -structural types or (possibly multidimensional) array thereof. +the types of all base classes and non-static data members are +structural types or (possibly multidimensional) arrays thereof. \end{itemize} \end{itemize} \pnum An \grammarterm{id-expression} naming -a non-type \grammarterm{template-parameter} of class type \tcode{T} +a constant template parameter of class type \tcode{T} denotes a static storage duration object of type \tcode{const T}, known as a \defn{template parameter object}, which is template-argument-equivalent\iref{temp.type} to the corresponding template argument after it has been converted -to the type of the \grammarterm{template-parameter}\iref{temp.arg.nontype}. +to the type of the template parameter\iref{temp.arg.nontype}. No two template parameter objects are template-argument-equivalent. \begin{note} If an \grammarterm{id-expression} names -a non-type non-reference \grammarterm{template-parameter}, +a non-reference constant template parameter, then it is a prvalue if it has non-class type. Otherwise, if it is of class type \tcode{T}, it is an lvalue and has type \tcode{const T}\iref{expr.prim.id.unqual}. @@ -426,10 +511,10 @@ using X = int; struct A {}; template void f() { - i++; // error: change of \grammarterm{template-parameter} value + i++; // error: change of template parameter value &x; // OK - &i; // error: address of non-reference template-parameter + &i; // error: address of non-reference template parameter &a; // OK int& ri = i; // error: attempt to bind non-const reference to temporary const int& cri = i; // OK, const reference binds to temporary @@ -440,8 +525,7 @@ \pnum \begin{note} -A non-type -\grammarterm{template-parameter} +A constant template parameter cannot be declared to have type \cv{} \keyword{void}. \begin{example} \begin{codeblock} @@ -452,8 +536,7 @@ \end{note} \pnum -A non-type -\grammarterm{template-parameter} +A constant template parameter \indextext{array!template parameter of type}% of type ``array of \tcode{T}'' or \indextext{function!template parameter of type}% @@ -473,7 +556,7 @@ \end{example} \pnum -A non-type template parameter declared with a type that +A constant template parameter declared with a type that contains a placeholder type with a \grammarterm{type-constraint} introduces the immediately-declared constraint of the \grammarterm{type-constraint} @@ -484,7 +567,7 @@ a template argument \iref{temp.arg} specified after \tcode{=} in a \grammarterm{template-parameter}. A default template argument may be specified for -any kind of \grammarterm{template-parameter} (type, non-type, template) +any kind of template parameter that is not a template parameter pack\iref{temp.variadic}. A default template argument may be specified in a template declaration. A default template argument shall not be specified in @@ -521,14 +604,15 @@ a default template argument, each subsequent \grammarterm{template-parameter} shall either have a default template argument supplied or -be a template parameter pack. +declare a template parameter pack. If a \grammarterm{template-parameter} of a primary class template, primary variable template, or alias template -is a template parameter pack, +declares a template parameter pack, it shall be the last \grammarterm{template-parameter}. -A template parameter pack of a function template -shall not be followed by another template parameter -unless that template parameter can be deduced from the +If a \grammarterm{template-parameter} of a function template +declares a template parameter pack, it +shall not be followed by another \grammarterm{template-parameter} +unless that template parameter is deducible from the parameter-type-list\iref{dcl.fct} of the function template or has a default argument\iref{temp.deduct}. A template parameter of a deduction guide template\iref{temp.deduct.guide} @@ -547,7 +631,7 @@ \indextext{\idxcode{<}!template and}% \pnum When parsing a default template argument -for a non-type \grammarterm{template-parameter}, +for a constant template parameter, the first non-nested \tcode{>} is taken as the end of the \grammarterm{template-parameter-list} rather than a greater-than operator. @@ -582,39 +666,15 @@ } \end{codeblock} \end{example} - -\pnum -If a \grammarterm{template-parameter} is a -\grammarterm{type-parameter} with an ellipsis prior to its -optional \grammarterm{identifier} or is a -\grammarterm{parameter-declaration} that declares a -pack\iref{dcl.fct}, then the \grammarterm{template-parameter} -is a template parameter pack\iref{temp.variadic}. -A template parameter pack that is a \grammarterm{parameter-declaration} whose type -contains one or more unexpanded packs is a pack expansion. Similarly, -a template parameter pack that is a \grammarterm{type-parameter} with a -\grammarterm{template-parameter-list} containing one or more unexpanded -packs is a pack expansion. -A type parameter pack with a \grammarterm{type-constraint} that -contains an unexpanded parameter pack is a pack expansion. -A template parameter pack that is a pack -expansion shall not expand a template parameter pack declared in the same -\grammarterm{template-parameter-list}. +The associated constraints of a template template parameter +shall not contain a concept-dependent constraint\iref{temp.constr.concept}. \begin{example} \begin{codeblock} -template // \tcode{Types} is a template type parameter pack - class Tuple; // but not a pack expansion - -template // \tcode{Dims} is a non-type template parameter pack - struct multi_array; // but not a pack expansion - -template - struct value_holder { - template struct apply { }; // \tcode{Values} is a non-type template parameter pack - }; // and a pack expansion - -template // error: \tcode{Values} expands template type parameter - struct static_array; // pack \tcode{T} within the same template parameter list +template< + template concept C, + template class TT // error: \tcode{C} forms a concept-dependent constraint +> +struct A {}; \end{codeblock} \end{example} @@ -651,8 +711,8 @@ \nontermdef{template-argument}\br constant-expression\br type-id\br - id-expression\br - braced-init-list + \opt{nested-name-specifier} template-name\br + nested-name-specifier \terminal{template} template-name \end{bnf} \pnum @@ -806,7 +866,7 @@ \item each \grammarterm{template-argument} matches the corresponding - \grammarterm{template-parameter}\iref{temp.arg}, + template parameter \iref{temp.arg}, \item substitution of each template argument into the following @@ -837,7 +897,7 @@ of a \grammarterm{simple-template-id} names a constrained non-function template or -a constrained template \grammarterm{template-parameter}, +a constrained template template parameter, and all \grammarterm{template-argument}{s} in the \grammarterm{simple-template-id} @@ -906,11 +966,6 @@ \pnum \indextext{argument!template}% -There are three forms of -\grammarterm{template-argument}, -corresponding to the three forms of -\grammarterm{template-parameter}: -type, non-type and template. The type and form of each \grammarterm{template-argument} specified in a @@ -986,8 +1041,8 @@ \begin{note} Names used in a \grammarterm{template-argument} are subject to access control where they appear. -Because a \grammarterm{template-parameter} is not a class member, -no access control applies. +Because a template parameter is not a class member, +no access control applies where the template parameter is used. \end{note} \begin{example} \begin{codeblock} @@ -1096,14 +1151,12 @@ A \grammarterm{template-argument} followed by an ellipsis is a pack expansion\iref{temp.variadic}. -\rSec2[temp.arg.type]{Template type arguments} +\rSec2[temp.arg.type]{Type template arguments} \pnum A \grammarterm{template-argument} -for a -\grammarterm{template-parameter} -which is a type +for a type template parameter shall be a \grammarterm{type-id}. @@ -1132,28 +1185,30 @@ A template type argument can be an incomplete type\iref{term.incomplete.type}. \end{note} -\rSec2[temp.arg.nontype]{Template non-type arguments} +\rSec2[temp.arg.nontype]{Constant template arguments} \pnum -If the type \tcode{T} of a \grammarterm{template-parameter}\iref{temp.param} -contains a placeholder type\iref{dcl.spec.auto} -or a placeholder for a deduced class type\iref{dcl.type.class.deduct}, -the type of the parameter is the type deduced -for the variable \tcode{x} in the invented declaration +A template argument $E$ for +a constant template parameter with declared type \tcode{T} +shall be such that the invented declaration \begin{codeblock} T x = @$E$@ ; \end{codeblock} -where $E$ is the template argument provided for the parameter. +satisfies the semantic constraints for the definition of +a \tcode{constexpr} variable with static storage duration\iref{dcl.constexpr}. +If \tcode{T} contains a placeholder type\iref{dcl.spec.auto} +or a placeholder for a deduced class type\iref{dcl.type.class.deduct}, +the type of the parameter is deduced from the above declaration. \begin{note} $E$ is a \grammarterm{template-argument} or (for a default template argument) an \grammarterm{initializer-clause}. \end{note} -If a deduced parameter type is not permitted -for a \grammarterm{template-parameter} declaration\iref{temp.param}, +If the parameter type thus deduced is not permitted +for a constant template parameter\iref{temp.param}, the program is ill-formed. \pnum -The value of a non-type \grammarterm{template-parameter} $P$ +The value of a constant template parameter $P$ of (possibly deduced) type \tcode{T} is determined from its template argument $A$ as follows. If \tcode{T} is not a class type and @@ -1197,11 +1252,11 @@ Otherwise, the value of $P$ is that of v. \pnum -For a non-type \grammarterm{template-parameter} of reference or pointer type, +For a constant 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): +in a constant template parameter of class type or subobject thereof, +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}, @@ -1210,6 +1265,19 @@ \item a subobject\iref{intro.object} of one of the above. \end{itemize} +\pnum +\begin{example} +\begin{codeblock} +template class A{}; +extern int x; +A a; // OK +void f(int p) { + constexpr int& r = p; // OK + A a; // error: a static constexpr \tcode{int\&} variable cannot be initialized to refer to \tcode{p} here +} +\end{codeblock} +\end{example} + \pnum \begin{example} \begin{codeblock} @@ -1260,7 +1328,7 @@ \begin{note} A \grammarterm{string-literal}\iref{lex.string} is not an acceptable \grammarterm{template-argument} -for a \grammarterm{template-parameter} of non-class type. +for a constant template parameter of non-class type. \begin{example} \begin{codeblock} template class X { @@ -1288,7 +1356,7 @@ is not an acceptable \grammarterm{template-argument} when the corresponding -\grammarterm{template-parameter} +template parameter has reference type. \begin{example} \begin{codeblock} @@ -1314,9 +1382,14 @@ A \grammarterm{template-argument} for a template -\grammarterm{template-parameter} -shall be the name of a class template or an alias template, expressed as -\grammarterm{id-expression}. +template parameter +shall be the name of a template. +For a \grammarterm{type-tt-parameter}, +the name shall denote a class template or alias template. +For a \grammarterm{variable-tt-parameter}, +the name shall denote a variable template. +For a \grammarterm{concept-tt-parameter}, +the name shall denote a concept. Only primary templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template @@ -1325,9 +1398,7 @@ \pnum Any partial specializations\iref{temp.spec.partial} associated with the primary template are considered when a -specialization based on the template -\grammarterm{template-parameter} -is instantiated. +specialization based on the template template parameter is instantiated. If a specialization is not reachable from the point of instantiation, and it would have been selected had it been reachable, the program is ill-formed, no diagnostic required. @@ -1349,23 +1420,41 @@ \end{example} \pnum -A \grammarterm{template-argument} matches a template -\grammarterm{template-parameter} \tcode{P} when -\tcode{P} is at least as specialized as the \grammarterm{template-argument} \tcode{A}. -In this comparison, if \tcode{P} is unconstrained, -the constraints on \tcode{A} are not considered. +A template template parameter \tcode{P} and +a \grammarterm{template-argument} \tcode{A} are +\defnx{compatible}{compatible!template template parameter and template argument} +if +\begin{itemize} +\item +\tcode{A} denotes a class template or an alias template and +\tcode{P} is a type template parameter, +\item +\tcode{A} denotes a variable template and +\tcode{P} is a variable template parameter, or +\item +\tcode{A} denotes a concept and +\tcode{P} is a concept template parameter. +\end{itemize} + +\pnum +A template \grammarterm{template-argument} \tcode{A} matches a template +template parameter \tcode{P} when +\tcode{A} and \tcode{P} are compatible and +\tcode{P} is at least as specialized as \tcode{A}, ignoring constraints +on \tcode{A} if \tcode{P} is unconstrained. If \tcode{P} contains a template parameter pack, then \tcode{A} also matches \tcode{P} if each of \tcode{A}'s template parameters -matches the corresponding template parameter in the +matches the corresponding template parameter declared in the \grammarterm{template-head} of \tcode{P}. -Two template parameters match if they are of the same kind (type, non-type, template), -for non-type \grammarterm{template-parameter}{s}, their types are -equivalent\iref{temp.over.link}, and for template \grammarterm{template-parameter}{s}, -each of their corresponding \grammarterm{template-parameter}{s} matches, recursively. -When \tcode{P}'s \grammarterm{template-head} contains a template parameter +Two template parameters match if they are of the same kind, +for constant template parameters, their types are +equivalent\iref{temp.over.link}, and for template template parameters, +each of their corresponding template parameters matches, recursively. +When \tcode{P}'s \grammarterm{template-head} contains a \grammarterm{template-parameter} +that declares a template parameter pack\iref{temp.variadic}, the template parameter pack will match zero or more template -parameters or template parameter packs in the \grammarterm{template-head} of -\tcode{A} with the same type and form as the template parameter pack in \tcode{P} +parameters or template parameter packs declared in the \grammarterm{template-head} of +\tcode{A} with the same type and form as the template parameter pack declared in \tcode{P} (ignoring whether those template parameters are template parameter packs). \begin{example} @@ -1425,7 +1514,7 @@ \end{example} \pnum -A template \grammarterm{template-parameter} \tcode{P} is +A template template parameter \tcode{P} is at least as specialized as a template \grammarterm{template-argument} \tcode{A} if, given the following rewrite to two function templates, the function template corresponding to \tcode{P} @@ -1447,12 +1536,12 @@ whose type is a specialization of \tcode{X} with template arguments corresponding to the template parameters from the respective function template where, -for each template parameter \tcode{PP} +for each \grammarterm{template-parameter} \tcode{PP} in the \grammarterm{template-head} of the function template, -a corresponding template argument \tcode{AA} is formed. +a corresponding \grammarterm{template-argument} \tcode{AA} is formed. If \tcode{PP} declares a template parameter pack, then \tcode{AA} is the pack expansion \tcode{PP...}\iref{temp.variadic}; -otherwise, \tcode{AA} is the \grammarterm{id-expression} \tcode{PP}. +otherwise, \tcode{AA} is an \grammarterm{id-expression} denoting \tcode{PP}. \end{itemize} If the rewrite produces an invalid type, then \tcode{P} is not at least as specialized as \tcode{A}. @@ -1480,11 +1569,13 @@ A \defn{constraint} is a sequence of logical operations and operands that specifies requirements on template arguments. The operands of a logical operation are constraints. -There are three different kinds of constraints: +There are five different kinds of constraints: \begin{itemize} \item conjunctions\iref{temp.constr.op}, -\item disjunctions\iref{temp.constr.op}, and -\item atomic constraints\iref{temp.constr.atomic}. +\item disjunctions\iref{temp.constr.op}, +\item atomic constraints\iref{temp.constr.atomic}, +\item concept-dependent constraints\iref{temp.constr.concept}, and +\item fold expanded constraints\iref{temp.constr.fold}. \end{itemize} \pnum @@ -1719,6 +1810,111 @@ \end{codeblock} \end{example} +\rSec3[temp.constr.concept]{Concept-dependent constraints} + +\pnum +A \defnadj{concept-dependent}{constraint} \tcode{CD} is +an atomic constraint whose expression is a concept-id \tcode{CI} whose +\grammarterm{concept-name} names a dependent concept named \tcode{C}. + +\pnum +To determine if \tcode{CD} is +\defnx{satisfied}{constraint!satisfaction!concept-dependent}, +the parameter mapping and template arguments are first +substituted into \tcode{C}. +If substitution results in an invalid concept-id in +the immediate context of the constraint\iref{temp.deduct.general}, +the constraint is not satisfied. +Otherwise, let \tcode{CI$'$} be +the normal form\iref{temp.constr.normal} of the concept-id +after substitution of \tcode{C}. +\begin{note} +Normalization of \tcode{CI} might be ill-formed; no diagnostics is required. +\end{note} + +\pnum +To form \tcode{CI$''$}, +each appearance of \tcode{C}{'s} template parameters in +the parameter mappings of the atomic constraints +(including concept-dependent constraints) +in \tcode{CI$'$} +is substituted with their respective arguments from +the parameter mapping of \tcode{CD} and the arguments of \tcode{CI}. + +\pnum +\tcode{CD} is satisfied if \tcode{CI$''$} is satisfied. +\begin{note} +Checking whether \tcode{CI$''$} is satisfied +can lead to further normalization of concept-dependent constraints. +\end{note} +%FIXME: "_" in the example below is not a valid identifier. +\begin{example} +\begin{codeblock} +template +concept C = true; + +template concept CC> +concept D = CC; + +template concept CT, + template concept> concept CU> +int f() requires CU; +int _ = f(); +\end{codeblock} +In this example, the associated constraint of \tcode{f} +is a concept-dependent constraint $CI$ +whose expression is the concept-id \tcode{CU} with the mapping +$\tcode{T} \mapsto \tcode{T}, \tcode{CT} \mapsto \tcode{CT}, \tcode{CU} \mapsto \tcode{CU}$.\\ +$CI'$ is the result of substituting \tcode{D} into $CI$.\\ +We consider the normal form $CI''$ of \tcode{D}, +which is \tcode{CC} with the mapping +$\tcode{T} \mapsto \tcode{T}, \tcode{CC} \mapsto \tcode{CC}$.\\ +By recursion, \tcode{C} is substituted in \tcode{CC} and then +normalized to the atomic constraint \tcode{true}, which is satisfied. +\end{example} + +\rSec3[temp.constr.fold]{Fold expanded constraint} + +\pnum +A \defnadj{fold expanded}{constraint} is formed from a constraint $C$ and +a \grammarterm{fold-operator} +which can either be \tcode{\&\&} or \tcode{||}. +A fold expanded constraint is a pack expansion\iref{temp.variadic}. +Let $N$ be the number of elements +in the pack expansion parameters\iref{temp.variadic}. + +\pnum +A fold expanded constraint whose \grammarterm{fold-operator} is \tcode{\&\&} +is satisfied if it is a valid pack expansion and +if $N = 0$ or if for each $i$ where $0 \le i < N$ in increasing order, +$C$ is satisfied +when replacing each pack expansion parameter +with the corresponding $i^\text{th}$ element. +No substitution takes place for any $i$ greater than +the smallest $i$ for which the constraint is not satisfied. + +\pnum +A fold expanded constraint whose \grammarterm{fold-operator} is \tcode{||} +is satisfied if it is a valid pack expansion, +$N > 0$, and if for $i$ where $0 \le i < N$ in increasing order, +there is a smallest $i$ for which $C$ is satisfied +when replacing each pack expansion parameter +with the corresponding $i^\text{th}$ element. +No substitution takes place for any $i$ greater than +the smallest $i$ for which the constraint is satisfied. + +\pnum +\begin{note} +If the pack expansion expands packs of different size, +then it is invalid and the fold expanded constraint is not satisfied. +\end{note} + +\pnum +Two fold expanded constraints are \defnadj{compatible for}{subsumption} +if their respective constraints both contain +an equivalent unexpanded pack\iref{temp.over.link}. + \rSec2[temp.constr.decl]{Constrained declarations} \pnum @@ -1868,13 +2064,30 @@ the normal forms of \tcode{E1} and \tcode{E2}. \item -The normal form of a concept-id \tcode{C} -is the normal form of the \grammarterm{constraint-expression} of \tcode{C}, -after substituting \tcode{A$_1$, A$_2$, ..., A$_n$} for -\tcode{C}{'s} respective template parameters in the -parameter mappings in each atomic constraint. +For a concept-id \tcode{C} termed \tcode{CI}: +\begin{itemize} +\item +If \tcode{C} names a dependent concept, +the normal form of \tcode{CI} is a concept-dependent constraint +whose concept-id is \tcode{CI} and +whose parameter mapping is the identity mapping. +\item +Otherwise, to form \tcode{CE}, +%FIXME: We're saying any Ai can be used to form CE. Do we have to try all +%FIXME: the Ais to check for ill-formedness or just the random one we picked? +%FIXME: Don't we want to form a CEi for each Ai? +any non-dependent concept template argument \tcode{A$_i$} +is substituted into the \grammarterm{constraint-expression} of \tcode{C}. +If any such substitution results in an invalid concept-id, +the program is ill-formed; no diagnostic is required. +The normal form of \tcode{CI} is the result of substituting, +in the normal form \tcode{N} of \tcode{CE}, +appearances of \tcode{C}{'s} template parameters +in the parameter mappings of the atomic constraints in \tcode{N} +with their respective arguments from \tcode{C}. If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required. +\end{itemize} \begin{example} \begin{codeblock} template concept A = T::value || true; @@ -1894,6 +2107,52 @@ in the parameter mapping. \end{example} +\item +For a \grammarterm{fold-operator} \tcode{Op} \iref{expr.prim.fold} +that is either \tcode{\&\&} or \tcode{||}: + \begin{itemize} + \item + The normal form of an expression \tcode{( ... Op E )} + is the normal form of \tcode{( E Op ... )}. + \item + The normal form of an expression \tcode{( E1 Op ... Op E2 )} + is the normal form of + \begin{itemize} + \item + \tcode{( E1 Op ... ) Op E2} if \tcode{E1} contains an unexpanded pack, or + \item + \tcode{E1 Op ( E2 Op ... )} otherwise. + \end{itemize} + \item + The normal form of an expression \tcode{F} of the form \tcode{( E Op ... )} + is as follows:\\ + If \tcode{E} contains an unexpanded concept template parameter pack, + it shall not contain an unexpanded template parameter pack of another kind. + Let \tcode{E$'$} be the normal form of \tcode{E}. + \begin{itemize} + \item + If \tcode{E} contains + an unexpanded concept template parameter pack \tcode{P$_k$} that + has corresponding template arguments in + the parameter mapping of any atomic constraint + (including concept-dependent constraints) of \tcode{E$'$}, + the number of arguments specified for all such \tcode{P$_k$} + shall be the same number $N$. + The normal form of \tcode{F} is the normal form of + \tcode{E$_0$ Op $\dotsb$ Op E$_{N-1}$} + after substituting in \tcode{E$_i$} + the respective $i^\text{th}$ concept argument of each \tcode{P$_k$}. + If any such substitution results in an invalid type or expression, + the program is ill-formed; no diagnostic is required. + \item + Otherwise, + the normal form of \tcode{F} is + a fold expanded constraint\iref{temp.constr.fold} whose + constraint is \tcode{E$'$} and whose + \grammarterm{fold-operator} is \tcode{Op}. + \end{itemize} + \end{itemize} + \item The normal form of any other expression \tcode{E} is the atomic constraint @@ -1935,6 +2194,65 @@ The associated constraints of \#3 are \tcode{requires (T x) \{ ++x; \}} (with mapping $\tcode{T} \mapsto \tcode{U}$). \end{example} + +\begin{example} +\begin{codeblock} +template +concept C = true; +template concept CT> +concept CC = CT; + +template concept> concept CT> + void f() requires CT; +template + void g() requires CC; +\end{codeblock} +The normal form of the associated constraints of \tcode{f} is +the concept-dependent constraint \tcode{CT}.\\ +The normal form of the associated constraints of \tcode{g} is +the atomic constraint \tcode{true}. +\end{example} + +\begin{example} +\begin{codeblock} +template +concept A = true; +template +concept B = A && true; // \tcode{B} subsumes \tcode{A} +template +concept C = true; +template +concept D = C && true; // \tcode{D} subsumes \tcode{C} + +template concept... CTs> +concept all_of = (CTs && ...); + +template requires all_of + constexpr int f(T) { return 1; } // \#1 +template requires all_of + constexpr int f(T) { return 2; } // \#2 + +static_assert(f(1) == 2); // ok +\end{codeblock} +The normal form of \tcode{all_of} is +the conjunction of the normal forms of \tcode{A} and \tcode{C}.\\ +Similarly, the normal form of \tcode{all_of} is +the conjunction of the normal forms of \tcode{B} and \tcode{D}.\\ +\#2 therefore is more constrained than \#1. +\end{example} + +\begin{example} +\begin{codeblock} +template concept> +struct wrapper {}; + +template concept... CTs> + int f(wrapper...) requires (CTs && ...); // error: fold expression contains + // different kinds of template parameters +\end{codeblock} +\end{example} + \indextext{constraint!normalization|)} \rSec2[temp.constr.order]{Partial ordering by constraints} @@ -1947,7 +2265,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)$ @@ -1960,7 +2278,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. % @@ -1971,11 +2289,17 @@ \item a disjunctive clause $P_i$ subsumes a conjunctive clause $Q_j$ if and only if there exists an atomic constraint $P_{ia}$ in $P_i$ for which there exists -an atomic constraint $Q_{jb}$ in $Q_j$ such that $P_{ia}$ subsumes $Q_{jb}$, and +an atomic constraint $Q_{jb}$ in $Q_j$ such that $P_{ia}$ subsumes $Q_{jb}$, \item an atomic constraint $A$ subsumes another atomic constraint $B$ if and only if $A$ and $B$ are identical using the -rules described in \ref{temp.constr.atomic}. +rules described in \ref{temp.constr.atomic}, and + +\item a fold expanded constraint $A$ subsumes +another fold expanded constraint $B$ +if they are compatible for subsumption, +have the same \grammarterm{fold-operator}, and +the constraint of $A$ subsumes that of $B$. \end{itemize} % \begin{example} @@ -2001,6 +2325,14 @@ \end{itemize} \end{note} +\pnum +The associated constraints \tcode{C} of a declaration \tcode{D} +\indextext{subsumption!eligible for}% +are \defnx{eligible for subsumption}{eligible!for subsumption} +%%% FIXME: This "definiton" needs work. Do we mean: +%%% "if C can be subsumed and C does not contain a concept-dependent constraint"? +unless \tcode{C} contains a concept-dependent constraint. + %%% FIXME: We need to substitute the deductions from partial ordering %%% into the constraints before comparing them, otherwise they will be %%% referring to unrelated template parameters. @@ -2010,7 +2342,8 @@ a declaration \tcode{D2} if \begin{itemize} \item \tcode{D1} and \tcode{D2} are both constrained declarations and -\tcode{D1}'s associated constraints subsume those of \tcode{D2}; or +\tcode{D1}'s associated constraints +are eligible for subsumption and subsume those of \tcode{D2}; or \item \tcode{D2} has no associated constraints. \end{itemize} @@ -2036,6 +2369,37 @@ g(0); // selects \#4 \end{codeblock} \end{example} +\begin{example} +\begin{codeblock} +template concept CT, typename T> +struct S {}; +template +concept A = true; + +template concept X, typename T> +int f(S) requires A { return 42; } // \#1 +template concept X, typename T> +int f(S) requires X { return 43; } // \#2 + +f(S{}); // ok, select \#1 because \#2 is not eligible for subsumption +\end{codeblock} +\end{example} + +\pnum +A non-template function \tcode{F1} is \defn{more partial-ordering-constrained} +than a non-template function \tcode{F2} if +\begin{itemize} +\item +they have the same non-object-parameter-type-lists\iref{dcl.fct}, and +\item +if they are member functions, both are direct members of the same class, and +\item +if both are non-static member functions, +they have the same types for their object parameters, and +\item +the declaration of \tcode{F1} is more constrained than +the declaration of \tcode{F2}. +\end{itemize} \rSec1[temp.type]{Type equivalence} @@ -2055,7 +2419,7 @@ \item the template parameter values determined by -their corresponding non-type template arguments\iref{temp.arg.nontype} +their corresponding constant template arguments\iref{temp.arg.nontype} are template-argument-equivalent (see below), and \item @@ -2422,7 +2786,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \opt{requires-clause} \terminal{->} simple-template-id \terminal{;} + \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \terminal{->} simple-template-id \opt{requires-clause} \terminal{;} \end{bnf} \pnum @@ -2532,7 +2896,6 @@ template struct A { enum E : T; }; -A a; template enum A::E : T { e1, e2 }; A::E e = A::e1; \end{codeblock} @@ -2713,11 +3076,27 @@ \end{codeblock} \end{example} +\pnum +A \defn{structured binding pack} is an \grammarterm{sb-identifier} +that introduces zero or more structured bindings\iref{dcl.struct.bind}. +\begin{example} +\begin{codeblock} +auto foo() -> int(&)[2]; + +template +void g() { + auto [...a] = foo(); // \tcode{a} is a structured binding pack containing two elements + auto [b, c, ...d] = foo(); // \tcode{d} is a structured binding pack containing zero elements +} +\end{codeblock} +\end{example} + \pnum A \defn{pack} is a template parameter pack, a function parameter pack, -or an \grammarterm{init-capture} pack. +an \grammarterm{init-capture} pack, or +a structured binding pack. The number of elements of a template parameter pack or a function parameter pack is the number of arguments provided for the parameter pack. @@ -2752,6 +3131,14 @@ \item if the template parameter pack is a \grammarterm{type-parameter}; the pattern is the corresponding \grammarterm{type-parameter} +without the ellipsis; + +\item +if the template parameter pack is a template template parameter; +the pattern is the corresponding +\grammarterm{type-tt-parameter}, +\grammarterm{variable-tt-parameter}, or +\grammarterm{concept-tt-parameter} without the ellipsis. \end{itemize} @@ -2789,6 +3176,9 @@ \item In a \grammarterm{fold-expression}\iref{expr.prim.fold}; the pattern is the \grammarterm{cast-expression} that contains an unexpanded pack. + +\item In a fold expanded constraint\iref{temp.constr.fold}; +the pattern is the constraint of that fold expanded constraint. \end{itemize} \begin{example} @@ -2852,16 +3242,20 @@ replacing each pack expansion parameter with its $i^\text{th}$ element. Such an element, in the context of the instantiation, is interpreted as follows: + \begin{itemize} \item if the pack is a template parameter pack, the element is -an \grammarterm{id-expression} -(for a non-type template parameter pack), -a \grammarterm{typedef-name} -(for a type template parameter pack declared without \tcode{template}), or -a \grammarterm{template-name} -(for a type template parameter pack declared with \tcode{template}), -designating the $i^\text{th}$ corresponding type or value template argument; +\begin{itemize} +\item +a \grammarterm{typedef-name} for a type template parameter pack, +\item +an \grammarterm{id-expression} for a constant template parameter pack, or +\item +a \grammarterm{template-name} for a template template parameter pack +\end{itemize} +designating the $i^\text{th}$ corresponding +type, constant, or template template argument; \item if the pack is a function parameter pack, the element is an @@ -2869,7 +3263,6 @@ designating the $i^\text{th}$ function parameter that resulted from instantiation of the function parameter pack declaration; -otherwise \item if the pack is an \grammarterm{init-capture} pack, @@ -2877,7 +3270,14 @@ designating the variable introduced by the $i^\text{th}$ \grammarterm{init-capture} that resulted from instantiation of -the \grammarterm{init-capture} pack declaration. +the \grammarterm{init-capture} pack declaration; +otherwise + +\item +if the pack is a structured binding pack, +the element is an \grammarterm{id-expression} +designating the $i^\textrm{th}$ structured binding in the pack +that resulted from the structured binding declaration. \end{itemize} When $N$ is zero, the instantiation of a pack expansion does not alter the syntactic interpretation of the enclosing construct, @@ -2976,6 +3376,9 @@ \tcode{,} & \tcode{void()} \\ \end{floattable} +\pnum +A fold expanded constraint is not instantiated\iref{temp.constr.fold}. + \pnum The instantiation of any other pack expansion produces a list of elements $\tcode{E}_1, \tcode{E}_2, \dotsc, \tcode{E}_N$. @@ -3303,9 +3706,9 @@ \end{example} \pnum -A non-type argument is non-specialized if it is the name of a non-type -parameter. -All other non-type arguments are specialized. +A constant template argument is non-specialized if it is the name of a constant +template parameter. +All other constant template arguments are specialized. \pnum Within the argument list of a partial specialization, @@ -3313,8 +3716,8 @@ \begin{itemize} \item -The type of a template parameter corresponding to a specialized non-type argument -shall not be dependent on a parameter of the partial specialization. +The type of a template parameter corresponding to a specialized constant template +argument shall not be dependent on a parameter of the partial specialization. \begin{example} \begin{codeblock} template struct C {}; @@ -3701,7 +4104,7 @@ \end{codeblock} \end{example} \begin{note} -Most expressions that use template parameters use non-type template +Most expressions that use template parameters use constant template parameters, but it is possible for an expression to reference a type parameter. For example, a template type parameter can be used in the @@ -3801,11 +4204,11 @@ \begin{itemize} \item they declare template parameters of the same kind, \item if either declares a template parameter pack, they both do, -\item if they declare non-type template parameters, +\item if they declare constant template parameters, they have equivalent types ignoring the use of \grammarterm{type-constraint}{s} for placeholder types, and -\item if they declare template template parameters, their template -parameters are equivalent. +\item if they declare template template parameters, +their \grammarterm{template-head}{s} are equivalent. \end{itemize} When determining whether types or \grammarterm{type-constraint}{s} are equivalent, the rules above are used to compare expressions @@ -3820,15 +4223,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 @@ -3897,16 +4304,30 @@ the more constrained template (if one exists) as determined below. \pnum -To produce the transformed template, for each type, non-type, or template +To produce the transformed template, for each +%FIXME: Don't we want to append "template parameter" to each of these? +%FIXME: As is, it reads as if it only applies to "conecpt". +%FIXME: E.g., we mean "type template parameter", not "type". +type, constant, +type template, variable template, or concept template parameter (including template parameter packs\iref{temp.variadic} -thereof) synthesize a unique type, value, or class template -respectively and substitute it for each occurrence of that parameter +thereof) synthesize a unique type, value, class template, +variable template, or concept, +respectively, and substitute it for each occurrence of that parameter in the function type of the template. \begin{note} The type replacing the placeholder -in the type of the value synthesized for a non-type template parameter +in the type of the value synthesized for a constant template parameter is also a unique synthesized type. \end{note} + +\pnum +%FIXME: What's a "synthesized template"? Do we mean the synthesized +%FIXME: template described above? If so, say so. +A synthesized template has the same \grammarterm{template-head} as +its corresponding template template parameter. + +\pnum Each function template $M$ that is a member function is considered to have a new first parameter of type $X(M)$, described below, @@ -4270,7 +4691,7 @@ \indextext{type concept|see{concept, type}}% A \defnx{type concept}{concept!type} is a concept whose prototype parameter -is a type \grammarterm{template-parameter}. +is a type template parameter. \rSec1[temp.res]{Name resolution} @@ -4361,7 +4782,7 @@ \begin{bnf} \nontermdef{typename-specifier}\br \keyword{typename} nested-name-specifier identifier\br - \keyword{typename} nested-name-specifier \terminal{\opt{template}} simple-template-id + \keyword{typename} nested-name-specifier \opt{\terminal{template}} simple-template-id \end{bnf} \pnum @@ -4444,7 +4865,8 @@ \item \grammarterm{parameter-declaration} in a \grammarterm{lambda-declarator} or \grammarterm{requirement-parameter-list}, unless that \grammarterm{parameter-declaration} appears in a default argument, or -\item \grammarterm{parameter-declaration} of a (non-type) \grammarterm{template-parameter}. +\item \grammarterm{parameter-declaration} of a \grammarterm{template-parameter} +(which necessarily declares a constant template parameter). \end{itemize} \end{itemize} \begin{example} @@ -4504,7 +4926,7 @@ Knowing which names are type names allows the syntax of every template to be checked in this way. \end{note} -The program is ill-formed, no diagnostic required, if: +The program is ill-formed, no diagnostic required, if \begin{itemize} \item no valid specialization, @@ -4623,7 +5045,7 @@ as a \grammarterm{template-name} or a \grammarterm{type-name}. When it is used with a \grammarterm{template-argument-list}, -as a \grammarterm{template-argument} for a template \grammarterm{template-parameter}, +as a \grammarterm{template-argument} for a type template template parameter, or as the final identifier in the \grammarterm{elaborated-type-specifier} of a friend class template declaration, it is a \grammarterm{template-name} that refers to the @@ -4717,21 +5139,21 @@ \end{example} \pnum -The name of a \grammarterm{template-parameter} +The name of a template parameter shall not be bound to any following declaration whose locus is contained by the scope -to which the template-parameter belongs. +to which the template parameter belongs. \begin{example} \begin{codeblock} template class Y { - int T; // error: \grammarterm{template-parameter} hidden + int T; // error: template parameter hidden void f() { - char T; // error: \grammarterm{template-parameter} hidden + char T; // error: template parameter hidden } friend void T(); // OK, no name bound }; -template class X; // error: hidden by \grammarterm{template-parameter} +template class X; // error: hidden by template parameter \end{codeblock} \end{example} @@ -4881,24 +5303,25 @@ \item in the definition of a nested class of a class template, the name of the nested class referenced as a member of the -current instantiation, or +current instantiation, \item in the definition of a class template partial specialization or a member of a class template partial specialization, the name of the class template followed by a template argument list equivalent to that of the partial specialization\iref{temp.spec.partial} -enclosed in \tcode{<>} (or an equivalent template alias specialization). +enclosed in \tcode{<>} (or an equivalent template alias specialization), or +\item +in the definition of a templated function, +the name of a local class\iref{class.local}. \end{itemize} \pnum A template argument that is equivalent to a template parameter can be used in place of that template parameter in a reference to the current instantiation. -For a template \grammarterm{type-parameter}, -a template argument is equivalent to a template parameter +A template argument is equivalent to a type template parameter if it denotes the same type. -For a non-type template parameter, -a template argument is equivalent to a template parameter +A template argument is equivalent to a constant template parameter if it is an \grammarterm{identifier} that names a variable that is equivalent to the template parameter. A variable is equivalent to a template parameter if @@ -5142,8 +5565,7 @@ \item denoted by a \grammarterm{simple-template-id} in which either the template name is a template parameter or any of the -template arguments is a dependent type or an expression that is type-dependent -or value-dependent or is a pack expansion, +template arguments is dependent\iref{temp.dep.temp}, \begin{footnote} This includes an injected-class-name\iref{class.pre} of a class template used without a \grammarterm{template-argument-list}. @@ -5182,7 +5604,7 @@ declared with a dependent type, \item associated by name lookup with -a non-type \grammarterm{template-parameter} +a constant template parameter declared with a type that contains a placeholder type\iref{dcl.spec.auto}, \item @@ -5198,6 +5620,28 @@ a structured binding declaration\iref{dcl.struct.bind} whose \grammarterm{brace-or-equal-initializer} is type-dependent, \item +associated by name lookup with a pack, +\begin{example} +\begin{codeblock} +struct C { }; + +void g(...); // \#1 + +template +void f() { + C arr[1]; + auto [...e] = arr; + g(e...); // calls \#2 +} + +void g(C); // \#2 + +int main() { + f(); +} +\end{codeblock} +\end{example} +\item associated by name lookup with an entity captured by copy\iref{expr.prim.lambda.capture} in a \grammarterm{lambda-expression} @@ -5208,6 +5652,10 @@ \mname{func}\iref{dcl.fct.def.general}, where any enclosing function is a template, a member of a class template, or a generic lambda, \item +associated by name lookup +with a result binding\iref{dcl.contract.res} of a function +whose return type is dependent, +\item a \grammarterm{conversion-function-id} that specifies a dependent type, or \item dependent @@ -5310,14 +5758,16 @@ \pnum An \grammarterm{id-expression} -is value-dependent if: +is value-dependent if \begin{itemize} \item -it is a concept-id and any of its arguments are dependent, +it is a concept-id and +its \grammarterm{concept-name} is dependent or +any of its arguments are dependent\iref{temp.dep.temp}, \item it is type-dependent, \item -it is the name of a non-type template parameter, +it is the name of a constant template parameter, \item it names a static data member that is a dependent member of the current instantiation and is not initialized in a \grammarterm{member-declarator}, @@ -5340,8 +5790,7 @@ \keyword{sizeof} \terminal{(} type-id \terminal{)}\br \keyword{typeid} \terminal{(} expression \terminal{)}\br \keyword{typeid} \terminal{(} type-id \terminal{)}\br -\keyword{alignof} \terminal{(} type-id \terminal{)}\br -\keyword{noexcept} \terminal{(} expression \terminal{)} +\keyword{alignof} \terminal{(} type-id \terminal{)} \end{ncsimplebnf} \begin{note} @@ -5351,20 +5800,28 @@ \pnum Expressions of the following form are value-dependent if either the -\grammarterm{type-id} -or -\grammarterm{simple-type-specifier} +\grammarterm{type-id}, +\grammarterm{simple-type-specifier}, or +\grammarterm{typename-specifier} is dependent or the \grammarterm{expression} or \grammarterm{cast-expression} +is value-dependent or +any \grammarterm{expression} in the \grammarterm{expression-list} +is value-dependent or +any \grammarterm{assignment-expression} in the \grammarterm{braced-init-list} is value-dependent: \begin{ncsimplebnf} simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +simple-type-specifier braced-init-list\br +typename-specifier braced-init-list\br \keyword{static_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{const_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{reinterpret_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br +\keyword{dynamic_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \terminal{(} type-id \terminal{)} cast-expression \end{ncsimplebnf} @@ -5375,6 +5832,13 @@ \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br fold-expression \end{ncsimplebnf} +unless the \grammarterm{identifier} is a structured binding pack +whose initializer is not dependent. + +\pnum +A \grammarterm{noexcept-expression}\iref{expr.unary.noexcept} +is value-dependent if +its \grammarterm{expression} involves a template parameter. \pnum An expression of the form \tcode{\&}\grammarterm{qualified-id} where the @@ -5394,22 +5858,26 @@ is dependent if the type it specifies is dependent. \pnum -A non-type +A constant \grammarterm{template-argument} is dependent if its type is dependent or the constant expression it specifies is value-dependent. \pnum -Furthermore, a non-type +Furthermore, a constant \grammarterm{template-argument} -is dependent if the corresponding non-type \grammarterm{template-parameter} +is dependent if the corresponding constant template parameter is of reference or pointer type and the \grammarterm{template-argument} designates or points to a member of the current instantiation or a member of a dependent type. \pnum -A template \grammarterm{template-parameter} is dependent if -it names a \grammarterm{template-parameter} or +%FIXME: "also" adds nothing here and reads like a note; remove it? +A template argument is also dependent if it is a pack expansion. + +\pnum +A template template parameter is dependent if +it names a template parameter or its terminal name is dependent. \rSec2[temp.dep.res]{Dependent name resolution} @@ -6157,13 +6625,15 @@ \end{example} \pnum -The \grammarterm{noexcept-specifier} of a function template specialization -is not instantiated along with the function declaration; it is instantiated -when needed\iref{except.spec}. If such an -\grammarterm{noexcept-specifier} is needed but has not yet been +The \grammarterm{noexcept-specifier} and \grammarterm{function-contract-specifier}s +of a function template specialization +are not instantiated along with the function declaration; +they are instantiated +when needed\iref{except.spec,dcl.contract.func}. If such a +specifier is needed but has not yet been instantiated, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the -\grammarterm{noexcept-specifier} is done as if it were being done as part +specifier is done as if it were being done as part of instantiating the declaration of the specialization at that point. \pnum @@ -6701,7 +7171,8 @@ is determined by the explicit specialization and is independent of those properties of the template. Similarly, -attributes appearing in the declaration of a template +attributes and \grammarterm{function-contract-specifier}s +appearing in the declaration of a template have no effect on an explicit specialization of that template. \begin{example} \begin{codeblock} @@ -6998,13 +7469,12 @@ \pnum Template arguments that are present shall be specified in the declaration -order of their corresponding -\grammarterm{template-parameter}{s}. +order of their corresponding template parameters. The template argument list shall not specify more \grammarterm{template-argument}{s} than there are corresponding \grammarterm{template-parameter}{s} -unless one of the \grammarterm{template-parameter}{s} is a template +unless one of the \grammarterm{template-parameter}{s} declares a template parameter pack. \begin{example} \begin{codeblock} @@ -7023,8 +7493,7 @@ \pnum Implicit conversions\iref{conv} will be performed on a function argument to convert it to the type of the corresponding function parameter if -the parameter type contains no -\grammarterm{template-parameter}{s} +the parameter type contains no template parameters that participate in template argument deduction. \begin{note} Template parameters do not participate in template argument deduction if @@ -7249,8 +7718,13 @@ cause template instantiations to occur in a different order or not at all, the program is ill-formed; no diagnostic required. \begin{note} -The equivalent substitution in exception specifications is -done only when the \grammarterm{noexcept-specifier} is instantiated, +The equivalent substitution in +exception specifications\iref{except.spec} +and function contract assertions\iref{dcl.contract.func} +is done only when +the \grammarterm{noexcept-specifier} +or \grammarterm{function-contract-specifier}, respectively, +is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression. \end{note} @@ -7377,7 +7851,8 @@ \item the specified member is not a template where a template is required, or \item -the specified member is not a non-type where a non-type is required. +the specified member is not a non-type, non-template where a non-type, +non-template is required. \end{itemize} \begin{example} \begin{codeblock} @@ -7399,7 +7874,7 @@ // Deduction fails in each of these cases: f(0); // \tcode{A} does not contain a member \tcode{Y} f(0); // The \tcode{Y} member of \tcode{B} is not a type - g(0); // The \tcode{N} member of \tcode{C} is not a non-type + g(0); // The \tcode{N} member of \tcode{C} is not a non-type, non-template name h(0); // The \tcode{TT} member of \tcode{D} is not a template } \end{codeblock} @@ -7418,7 +7893,7 @@ \end{codeblock} \end{example} \item -Attempting to give an invalid type to a non-type template parameter. +Attempting to give an invalid type to a constant template parameter. \begin{example} \begin{codeblock} template struct S {}; @@ -7426,7 +7901,7 @@ class X { int m; }; -int i0 = f(0); // \#1 uses a value of non-structural type \tcode{X} as a non-type template argument +int i0 = f(0); // \#1 uses a value of non-structural type \tcode{X} as a constant template argument \end{codeblock} \end{example} @@ -7445,6 +7920,13 @@ Attempting to create a function type in which a parameter has a type of \keyword{void}, or in which the return type is a function type or array type. + +\item +%FIXME: What's it mean to "give" a type "to" a parameter? +%FIXME: See also "Attempting to give an invalid type to ..." above. +Attempting to give to +an explicit object parameter of a lambda's function call operator +a type not permitted for such\iref{expr.prim.lambda.closure}. \end{itemize} \end{note} @@ -7474,12 +7956,12 @@ Template argument deduction is done by comparing each function template parameter type (call it \tcode{P}) -that contains \grammarterm{template-parameter}{s} that participate in template argument deduction +that contains template parameters that participate in template argument deduction with the type of the corresponding argument of the call (call it \tcode{A}) as described below. If removing references and cv-qualifiers from \tcode{P} gives -\tcode{std::initializer_list} +$\tcode{std::initializer_list}$ or $\tcode{P}'\tcode{[N]}$ for some $\tcode{P}'$ and \tcode{N} and the argument is a non-empty initializer list\iref{dcl.init.list}, then deduction is @@ -7487,7 +7969,7 @@ taking $\tcode{P}'$ as separate function template parameter types $\tcode{P}'_i$ and the $i^\text{th}$ initializer element as the corresponding argument. -In the $\tcode{P}'\tcode{[N]}$ case, if \tcode{N} is a non-type template parameter, +In the $\tcode{P}'\tcode{[N]}$ case, if \tcode{N} is a constant template parameter, \tcode{N} is deduced from the length of the initializer list. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context\iref{temp.deduct.type}. @@ -7721,8 +8203,7 @@ \tcode{A}, the type deduction fails. \begin{note} -If a -\grammarterm{template-parameter} +If a template parameter is not used in any of the function parameters of a function template, or is used only in a non-deduced context, its corresponding \grammarterm{template-argument} @@ -7741,10 +8222,11 @@ the parameter is treated as a non-deduced context. \item If the argument is an overload set (not containing function templates), trial -argument deduction is attempted using each of the members of the set. If -deduction succeeds for only one of the overload set members, that member is -used as the argument value for the deduction. If deduction succeeds for more than -one member of the overload set the parameter is treated as a non-deduced context. +argument deduction is attempted using each of the members of the set +whose associated constraints\iref{temp.constr.constr} are satisfied. +If all successful deductions yield the same deduced \tcode{A}, +that deduced \tcode{A} is the result of deduction; +otherwise, the parameter is treated as a non-deduced context. \end{itemize} \pnum @@ -7780,6 +8262,21 @@ \end{codeblock} \end{example} +\pnum +\begin{example} +\begin{codeblock} +// All arguments for placeholder type deduction\iref{dcl.type.auto.deduct} yield the same deduced type. +template struct X { + static void f(short) requires B; // \#1 + static void f(short); // \#2 +}; +void test() { + auto x = &X::f; // OK, deduces \tcode{void(*)(short)}, selects \#1 + auto y = &X::f; // OK, deduces \tcode{void(*)(short)}, selects \#2 +} +\end{codeblock} +\end{example} + \rSec3[temp.deduct.funcaddr]{Deducing template arguments taking the address of a function template} \pnum @@ -8112,8 +8609,8 @@ is compared with an actual type (call it \tcode{A}), and an attempt is made to find template argument values (a type for a type -parameter, a value for a non-type parameter, or a template for a -template parameter) that will make +parameter, a value for a constant template parameter, or a template for a +template template parameter) that will make \tcode{P}, after substitution of the deduced values (call it the deduced \tcode{A}), @@ -8149,7 +8646,7 @@ A given type \tcode{P} can be composed from a number of other -types, templates, and non-type values: +types, templates, and constant template argument values: \begin{itemize} \item @@ -8161,7 +8658,7 @@ \item A type that is a specialization of a class template (e.g., \tcode{A}) -includes the types, templates, and non-type values referenced by the +includes the types, templates, and constant template argument values referenced by the template argument list of the specialization. \item An array type includes the array element type and the value of the @@ -8169,7 +8666,7 @@ \end{itemize} \pnum -In most cases, the types, templates, and non-type values that are used +In most cases, the types, templates, and constant template argument values that are used to compose \tcode{P} participate in template argument deduction. @@ -8185,7 +8682,7 @@ explicitly specified, template argument deduction fails. \begin{note} Under \ref{temp.deduct.call}, -if \tcode{P} contains no \grammarterm{template-parameter}{s} that appear +if \tcode{P} contains no template parameters that appear in deduced contexts, no deduction is done, so \tcode{P} and \tcode{A} need not have the same form. \end{note} @@ -8205,7 +8702,7 @@ \item The \grammarterm{expression} of a \grammarterm{decltype-specifier}. \item -A non-type template argument or an array bound in which a subexpression +A constant template argument or an array bound in which a subexpression references a template parameter. \item A template parameter used in the parameter type of a function parameter that @@ -8213,16 +8710,22 @@ deduction is being done. \item A function parameter for which the associated argument is an -overload set\iref{over.over}, and one or more of the following apply: +overload set such that one or more of the following apply: \begin{itemize} \item -more than one function matches the function parameter type (resulting in -an ambiguous deduction), or +functions whose associated constraints are satisfied and +that do not all have the same function type +match the function parameter type (resulting in an ambiguous deduction), or \item -no function matches the function parameter type, or +no function whose associated constraints are satisfied +matches the function parameter type, or \item the overload set supplied as an argument contains one or more function templates. \end{itemize} +\begin{tailnote} +A particular function from the overload set is selected\iref{over.over} +after template argument deduction has succeeded\iref{temp.over}. +\end{tailnote} \item A function parameter for which the associated argument is an initializer list\iref{dcl.init.list} but the parameter does not have a type for which deduction from an initializer list is specified\iref{temp.deduct.call}. @@ -8357,12 +8860,12 @@ \end{example} \pnum -A template type argument -\tcode{T}, -a template template argument -\tcode{TT}, -or a template non-type argument -\tcode{i} +A type template argument \tcode{T}, +a constant template argument \tcode{i}, +a template template argument \tcode{TT} +denoting a class template or an alias template, or +a template template argument \tcode{VV} +denoting a variable template or a concept can be deduced if \tcode{P} and @@ -8379,6 +8882,7 @@ @\opt{TT}@ @\opt{TT}@ @\opt{TT}@ +@\opt{TT}@ @\opt{TT}@<> \end{codeblock} where @@ -8389,15 +8893,15 @@ is a non-deduced context in \tcode{P} or \tcode{A}, or is the same non-dependent type in \tcode{P} and \tcode{A}, -\item -\tcode{\opt{TT}} represents either a class template or -a template template parameter, - \item \tcode{\opt{i}} represents an expression that either is an \tcode{i}, is value-dependent in \tcode{P} or \tcode{A}, or -has the same constant value in \tcode{P} and \tcode{A}, and +has the same constant value in \tcode{P} and \tcode{A}, + +\item +\tcode{\opt{TT}} represents either a class template or +a template template parameter, and \item \tcode{\keyword{noexcept}(\opt{i})} represents an @@ -8413,22 +8917,18 @@ \end{note} Similarly, -\tcode{} -represents template argument lists where at least one argument contains a -\tcode{T}, -\tcode{} -represents template argument lists where at least one argument contains an -\tcode{i} +\tcode{<$X$>} represents template argument lists where +at least one argument contains an $X$, where +$X$ is one of \tcode{T}, \tcode{i}, \tcode{TT}, or \tcode{VV}; and \tcode{<>} represents template argument lists where no argument contains a -\tcode{T} -or an -\tcode{i}. +\tcode{T}, an \tcode{i}, a \tcode{TT}, or a \tcode{VV}. \pnum -If \tcode{P} has a form that contains \tcode{} -or \tcode{}, then each argument $\mathtt{P}_i$ of the +If \tcode{P} has a form that contains +\tcode{}, \tcode{}, \tcode{}, or \tcode{}, +then each argument $\mathtt{P}_i$ of the respective template argument list of \tcode{P} is compared with the corresponding argument $\mathtt{A}_i$ of the corresponding template argument list of \tcode{A}. If the template argument list @@ -8549,7 +9049,7 @@ \pnum When the value of the argument -corresponding to a non-type template parameter \tcode{P} +corresponding to a constant template parameter \tcode{P} that is declared with a dependent type is deduced from an expression, the template parameters in the type of \tcode{P} @@ -8631,8 +9131,8 @@ \pnum \begin{note} -If, in the declaration of a function template with a non-type -template parameter, the non-type template parameter +If, in the declaration of a function template with a constant +template parameter, the constant template parameter is used in a subexpression in the function parameter list, the expression is a non-deduced context as specified above. \begin{example} @@ -8682,9 +9182,7 @@ \begin{footnote} Although the \grammarterm{template-argument} -corresponding to a -\grammarterm{template-parameter} -of type +corresponding to a template parameter of type \tcode{bool} can be deduced from an array bound, the resulting value will always be \tcode{true} @@ -8752,8 +9250,7 @@ \pnum The \grammarterm{template-argument} -corresponding to a template -\grammarterm{template-parameter} +corresponding to a template template parameter is deduced from the type of the \grammarterm{template-argument} of a class template specialization used in the argument list of a function call. @@ -8890,8 +9387,7 @@ \pnum \begin{example} Here is an example involving conversions on a function argument involved in -\grammarterm{template-argument} -deduction: +template argument deduction: \begin{codeblock} template struct B { @\commentellip@ }; template struct D : public B { @\commentellip@ }; @@ -8907,8 +9403,7 @@ \pnum \begin{example} Here is an example involving conversions on a function argument not involved in -\grammarterm{template-parameter} -deduction: +template argument deduction: \begin{codeblock} template void f(T*,int); // \#1 template void f(T,char); // \#2 diff --git a/source/text.tex b/source/text.tex new file mode 100644 index 0000000000..f58f5f4fa6 --- /dev/null +++ b/source/text.tex @@ -0,0 +1,13457 @@ +%!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 { + // floating-point format for primitive numerical conversion + enum class @\libglobal{chars_format}@ { + @\libmember{scientific}{chars_format}@ = @\unspec@, + @\libmember{fixed}{chars_format}@ = @\unspec@, + @\libmember{hex}{chars_format}@ = @\unspec@, + @\libmember{general}{chars_format}@ = fixed | scientific + }; + + // \ref{charconv.to.chars}, primitive numerical output conversion + struct @\libglobal{to_chars_result}@ { // freestanding + char* @\libmember{ptr}{to_chars_result}@; + errc @\libmember{ec}{to_chars_result}@; + friend bool operator==(const to_chars_result&, const to_chars_result&) = default; + constexpr explicit operator bool() const noexcept { return ec == errc{}; } + }; + + constexpr to_chars_result to_chars(char* first, char* last, // freestanding + @\placeholder{integer-type}@ value, int base = 10); + to_chars_result to_chars(char* first, char* last, // freestanding + bool value, int base = 10) = delete; + + to_chars_result to_chars(char* first, char* last, // freestanding-deleted + @\placeholder{floating-point-type}@ value); + to_chars_result to_chars(char* first, char* last, // freestanding-deleted + @\placeholder{floating-point-type}@ value, chars_format fmt); + to_chars_result to_chars(char* first, char* last, // freestanding-deleted + @\placeholder{floating-point-type}@ value, chars_format fmt, int precision); + + // \ref{charconv.from.chars}, primitive numerical input conversion + struct @\libglobal{from_chars_result}@ { // freestanding + const char* @\libmember{ptr}{from_chars_result}@; + errc @\libmember{ec}{from_chars_result}@; + friend bool operator==(const from_chars_result&, const from_chars_result&) = default; + constexpr explicit operator bool() const noexcept { return ec == errc{}; } + }; + + constexpr from_chars_result from_chars(const char* first, const char* last, // freestanding + @\placeholder{integer-type}@& value, int base = 10); + + from_chars_result from_chars(const char* first, const char* last, // freestanding-deleted + @\placeholder{floating-point-type}@& value, + chars_format fmt = chars_format::general); +} +\end{codeblock} + +\pnum +The type \tcode{chars_format} is a bitmask type\iref{bitmask.types} +with elements \tcode{scientific}, \tcode{fixed}, and \tcode{hex}. + +\pnum +The types \tcode{to_chars_result} and \tcode{from_chars_result} +have the data members and special members specified above. +They have no base classes or members other than those specified. + +\rSec2[charconv.to.chars]{Primitive numeric output conversion} + +\pnum +All functions named \tcode{to_chars} +convert \tcode{value} into a character string +by successively filling the range +\range{first}{last}, +where \range{first}{last} is required to be a valid range. +If the member \tcode{ec} +of the return value +is such that the value +is equal to the value of a value-initialized \tcode{errc}, +the conversion was successful +and the member \tcode{ptr} +is the one-past-the-end pointer of the characters written. +Otherwise, +the member \tcode{ec} has the value \tcode{errc::value_too_large}, +the member \tcode{ptr} has the value \tcode{last}, +and the contents of the range \range{first}{last} are unspecified. + +\pnum +The functions that take a floating-point \tcode{value} +but not a \tcode{precision} parameter +ensure that the string representation +consists of the smallest number of characters +such that +there is at least one digit before the radix point (if present) and +parsing the representation using the corresponding \tcode{from_chars} function +recovers \tcode{value} exactly. +\begin{note} +This guarantee applies only if +\tcode{to_chars} and \tcode{from_chars} +are executed on the same implementation. +\end{note} +If there are several such representations, +the representation with the smallest difference from +the floating-point argument value is chosen, +resolving any remaining ties using rounding according to +\tcode{round_to_nearest}\iref{round.style}. + +\pnum +The functions taking a \tcode{chars_format} parameter +determine the conversion specifier for \tcode{printf} as follows: +The conversion specifier is +\tcode{f} if \tcode{fmt} is \tcode{chars_format::fixed}, +\tcode{e} if \tcode{fmt} is \tcode{chars_format::scientific}, +\tcode{a} (without leading \tcode{"0x"} in the result) +if \tcode{fmt} is \tcode{chars_format::hex}, +and +\tcode{g} if \tcode{fmt} is \tcode{chars_format::general}. + +\indexlibraryglobal{to_chars}% +\begin{itemdecl} +constexpr to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{base} has a value between 2 and 36 (inclusive). + +\pnum +\effects +The value of \tcode{value} is converted +to a string of digits in the given base +(with no redundant leading zeroes). +Digits in the range 10..35 (inclusive) +are represented as lowercase characters \tcode{a}..\tcode{z}. +If \tcode{value} is less than zero, +the representation starts with \tcode{'-'}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\indexlibraryglobal{to_chars}% +\begin{itemdecl} +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\tcode{value} is converted to a string +in the style of \tcode{printf} +in the \tcode{"C"} locale. +The conversion specifier is \tcode{f} or \tcode{e}, +chosen according to the requirement for a shortest representation +(see above); +a tie is resolved in favor of \tcode{f}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\indexlibraryglobal{to_chars}% +\begin{itemdecl} +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{fmt} has the value of +one of the enumerators of \tcode{chars_format}. + +\pnum +\effects +\tcode{value} is converted to a string +in the style of \tcode{printf} +in the \tcode{"C"} locale. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\indexlibraryglobal{to_chars}% +\begin{itemdecl} +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, + chars_format fmt, int precision); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{fmt} has the value of +one of the enumerators of \tcode{chars_format}. + +\pnum +\effects +\tcode{value} is converted to a string +in the style of \tcode{printf} +in the \tcode{"C"} locale +with the given precision. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\xrefc{7.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 +Subclause \ref{localization} describes components that \Cpp{} programs may use to +encapsulate (and therefore be more portable when confronting) +cultural differences. +The locale facility includes +internationalization support for character classification and string collation, +numeric, monetary, and date/time formatting and parsing, and +message retrieval. + +\pnum +The following subclauses describe components for +locales themselves, +the standard facets, and +facilities from the C library, +as summarized in \tref{localization.summary}. + +\begin{libsumtab}{Localization library summary}{localization.summary} +\ref{locales} & Locales & \tcode{} \\ +\ref{locale.categories} & Standard \tcode{locale} categories & \\ \rowsep +\ref{c.locales} & C library locales & \tcode{} \\ \rowsep +\end{libsumtab} + +\rSec2[locale.syn]{Header \tcode{} synopsis} + +\indexheader{locale}% +\begin{codeblock} +namespace std { + // \ref{locale}, locale + class locale; + template const Facet& use_facet(const locale&); + template bool has_facet(const locale&) noexcept; + + // \ref{locale.convenience}, convenience interfaces + template bool isspace (charT c, const locale& loc); + template bool isprint (charT c, const locale& loc); + template bool iscntrl (charT c, const locale& loc); + template bool isupper (charT c, const locale& loc); + template bool islower (charT c, const locale& loc); + template bool isalpha (charT c, const locale& loc); + template bool isdigit (charT c, const locale& loc); + template bool ispunct (charT c, const locale& loc); + template bool isxdigit(charT c, const locale& loc); + template bool isalnum (charT c, const locale& loc); + template bool isgraph (charT c, const locale& loc); + template bool isblank (charT c, const locale& loc); + template charT toupper(charT c, const locale& loc); + template charT tolower(charT c, const locale& loc); + + // \ref{category.ctype}, ctype + class ctype_base; + template class ctype; + template<> class ctype; // specialization + template class ctype_byname; + class codecvt_base; + template class codecvt; + template class codecvt_byname; + + // \ref{category.numeric}, numeric + template> + class num_get; + template> + class num_put; + template + class numpunct; + template + class numpunct_byname; + + // \ref{category.collate}, collation + template class collate; + template class collate_byname; + + // \ref{category.time}, date and time + class time_base; + template> + class time_get; + template> + class time_get_byname; + template> + class time_put; + template> + class time_put_byname; + + // \ref{category.monetary}, money + class money_base; + template> + class money_get; + template> + class money_put; + template + class moneypunct; + template + class moneypunct_byname; + + // \ref{category.messages}, message retrieval + class messages_base; + template class messages; + template class messages_byname; +} +\end{codeblock} + +\pnum +The header \libheader{locale} +defines classes and declares functions +that encapsulate and manipulate the information peculiar to a locale. +\begin{footnote} +In this subclause, the type name \tcode{tm} +is an incomplete type that is defined in \libheaderref{ctime}. +\end{footnote} + +\rSec2[locales]{Locales} + +\rSec3[locale]{Class \tcode{locale}} + +\rSec4[locale.general]{General} + +\begin{codeblock} +namespace std { + class locale { + public: + // \ref{locale.types}, types + // \ref{locale.facet}, class \tcode{locale::facet} + class facet; + // \ref{locale.id}, class \tcode{locale::id} + class id; + // \ref{locale.category}, type \tcode{locale::category} + using category = int; + static const category // values assigned here are for exposition only + none = 0, + collate = 0x010, ctype = 0x020, + monetary = 0x040, numeric = 0x080, + time = 0x100, messages = 0x200, + all = collate | ctype | monetary | numeric | time | messages; + + // \ref{locale.cons}, construct/copy/destroy + locale() noexcept; + locale(const locale& other) noexcept; + explicit locale(const char* std_name); + explicit locale(const string& std_name); + locale(const locale& other, const char* std_name, category); + locale(const locale& other, const string& std_name, category); + template locale(const locale& other, Facet* f); + locale(const locale& other, const locale& one, category); + ~locale(); // not virtual + const locale& operator=(const locale& other) noexcept; + + // \ref{locale.members}, locale operations + template locale combine(const locale& other) const; + string name() const; + text_encoding encoding() const; + + bool operator==(const locale& other) const; + + template + bool operator()(const basic_string& s1, + const basic_string& s2) const; + + // \ref{locale.statics}, global locale objects + static locale global(const locale&); + static const locale& classic(); + }; +} +\end{codeblock} + +\pnum +Class \tcode{locale} implements a type-safe polymorphic set of facets, +indexed by facet \textit{type}. +In other words, a facet has a dual role: +in one sense, it's just a class interface; +at the same time, it's an index into a locale's set of facets. + +\pnum +Access to the facets of a \tcode{locale} is via two function templates, +\tcode{use_facet<>} and \tcode{has_facet<>}. + +\pnum +\begin{example} +An iostream \tcode{operator<<} can be implemented as: +\begin{footnote} +Note that in the call to \tcode{put}, +the stream is implicitly converted +to an \tcode{ostreambuf_iterator}. +\end{footnote} + +\begin{codeblock} +template +basic_ostream& +operator<< (basic_ostream& s, Date d) { + typename basic_ostream::sentry cerberos(s); + if (cerberos) { + tm tmbuf; d.extract(tmbuf); + bool failed = + use_facet>>( + s.getloc()).put(s, s, s.fill(), &tmbuf, 'x').failed(); + if (failed) + s.setstate(s.badbit); // can throw + } + return s; +} +\end{codeblock} +\end{example} + +\pnum +In the call to \tcode{use_facet(loc)}, +the type argument chooses a facet, +making available all members of the named type. +If \tcode{Facet} is not present in a locale, +it throws the standard exception \tcode{bad_cast}. +A \Cpp{} program can check if a locale implements a particular facet +with the function template \tcode{has_facet()}. +User-defined facets may be installed in a locale, and +used identically as may standard facets. + +\pnum +\begin{note} +All locale semantics are accessed via +\tcode{use_facet<>} and \tcode{has_facet<>}, +except that: + +\begin{itemize} +\item +A member operator template +\begin{codeblock} +operator()(const basic_string&, const basic_string&) +\end{codeblock} +is provided so that a locale can be used as a predicate argument to +the standard collections, to collate strings. +\item +Convenient global interfaces are provided for +traditional \tcode{ctype} functions such as +\tcode{isdigit()} and \tcode{isspace()}, +so that given a locale object \tcode{loc} +a \Cpp{} program can call \tcode{isspace(c, loc)}. +(This eases upgrading existing extractors\iref{istream.formatted}.) +\end{itemize} +\end{note} + +\pnum +Once a facet reference is obtained from a locale object +by calling \tcode{use_facet<>}, +that reference remains usable, +and the results from member functions of it may be cached and re-used, +as long as some locale object refers to that facet. + +\pnum +In successive calls to a locale facet member function +on a facet object installed in the same locale, +the returned result shall be identical. + +\pnum +A \tcode{locale} constructed +from a name string (such as \tcode{"POSIX"}), or +from parts of two named locales, has a name; +all others do not. +Named locales may be compared for equality; +an unnamed locale is equal only to (copies of) itself. +For an unnamed locale, \tcode{locale::name()} returns the string \tcode{"*"}. + +\pnum +Whether there is +one global locale object for the entire program or +one global locale object per thread +is \impldef{whether locale object is global or per-thread}. +Implementations should provide one global locale object per thread. +If there is a single global locale object for the entire program, +implementations are not required to +avoid data races on it\iref{res.on.data.races}. + +\rSec4[locale.types]{Types} + +\rSec5[locale.category]{Type \tcode{locale::category}} + +\indexlibrarymember{locale}{category}% +\begin{itemdecl} +using category = int; +\end{itemdecl} + +\pnum +\textit{Valid} \tcode{category} values +include the \tcode{locale} member bitmask elements +\tcode{collate}, +\tcode{ctype}, +\tcode{monetary}, +\tcode{numeric}, +\tcode{time}, +and +\tcode{messages}, +each of which represents a single locale category. +In addition, \tcode{locale} member bitmask constant \tcode{none} +is defined as zero and represents no category. +And \tcode{locale} member bitmask constant \tcode{all} +is defined such that the expression +\begin{codeblock} +(collate | ctype | monetary | numeric | time | messages | all) == all +\end{codeblock} +is \tcode{true}, +and represents the union of all categories. +Further, the expression \tcode{(X | Y)}, +where \tcode{X} and \tcode{Y} each represent a single category, +represents the union of the two categories. + +\pnum +\tcode{locale} member functions +expecting a \tcode{category} argument +require one of the \tcode{category} values defined above, or +the union of two or more such values. +Such a \tcode{category} value identifies a set of locale categories. +Each locale category, in turn, identifies a set of locale facets, +including at least those shown in \tref{locale.category.facets}. + +\begin{floattable}{Locale category facets}{locale.category.facets} +{ll} +\topline +\lhdr{Category} & \rhdr{Includes facets} \\ \capsep +collate & \tcode{collate}, \tcode{collate} \\ \rowsep +ctype & \tcode{ctype}, \tcode{ctype} \\ + & \tcode{codecvt} \\ + & \tcode{codecvt} \\ \rowsep +monetary & \tcode{moneypunct}, \tcode{moneypunct} \\ + & \tcode{moneypunct}, \tcode{moneypunct} \\ + & \tcode{money_get}, \tcode{money_get} \\ + & \tcode{money_put}, \tcode{money_put} \\ \rowsep +numeric & \tcode{numpunct}, \tcode{numpunct} \\ + & \tcode{num_get}, \tcode{num_get} \\ + & \tcode{num_put}, \tcode{num_put} \\ \rowsep +time & \tcode{time_get}, \tcode{time_get} \\ + & \tcode{time_put}, \tcode{time_put} \\ \rowsep +messages & \tcode{messages}, \tcode{messages} \\ +\end{floattable} + +\pnum +For any locale \tcode{loc} +either constructed, or returned by \tcode{locale::classic()}, +and any facet \tcode{Facet} shown in \tref{locale.category.facets}, +\tcode{has_facet(loc)} is \tcode{true}. +Each \tcode{locale} member function +which takes a \tcode{locale::category} argument +operates on the corresponding set of facets. + +\pnum +An implementation is required to provide those specializations +for facet templates identified as members of a category, and +for those shown in \tref{locale.spec}. + +\begin{floattable}{Required specializations}{locale.spec} +{ll} +\topline +\lhdr{Category} & \rhdr{Includes facets} \\ \capsep +collate & \tcode{collate_byname}, \tcode{collate_byname} \\ \rowsep +ctype & \tcode{ctype_byname}, \tcode{ctype_byname} \\ + & \tcode{codecvt_byname} \\ + & \tcode{codecvt_byname} \\ \rowsep +monetary & \tcode{moneypunct_byname} \\ + & \tcode{moneypunct_byname} \\ + & \tcode{money_get} \\ + & \tcode{money_put} \\ \rowsep +numeric & \tcode{numpunct_byname}, \tcode{numpunct_byname} \\ + & \tcode{num_get}, \tcode{num_put} \\ \rowsep +time & \tcode{time_get} \\ + & \tcode{time_get_byname} \\ + & \tcode{time_get} \\ + & \tcode{time_get_byname} \\ + & \tcode{time_put} \\ + & \tcode{time_put_byname} \\ + & \tcode{time_put} \\ + & \tcode{time_put_byname} \\ \rowsep +messages & \tcode{messages_byname}, \tcode{messages_byname} \\ +\end{floattable} + + +\pnum +The provided implementation of members of +facets \tcode{num_get} and \tcode{num_put} +calls \tcode{use_fac\-et(l)} only for facet \tcode{F} of +types \tcode{numpunct} and \tcode{ctype}, +and for locale \tcode{l} the value obtained by calling member \tcode{getloc()} +on the \tcode{ios_base\&} argument to these functions. + +\pnum +In declarations of facets, +a template parameter with name \tcode{InputIterator} or \tcode{OutputIterator} +indicates the set of all possible specializations on parameters that meet the +\oldconcept{InputIterator} requirements or +\oldconcept{OutputIterator} requirements, +respectively\iref{iterator.requirements}. +A template parameter with name \tcode{C} represents +the set of types containing \keyword{char}, \keyword{wchar_t}, and any other +\impldef{set of character container types +that iostreams templates can be instantiated for} +character container types\iref{defns.character.container} +that meet the requirements for a character +on which any of the iostream components can be instantiated. +A template parameter with name \tcode{International} +represents the set of all possible specializations on a bool parameter. + +\rSec5[locale.facet]{Class \tcode{locale::facet}} + +\indexlibrarymember{locale}{facet}% +\begin{codeblock} +namespace std { + class locale::facet { + protected: + explicit facet(size_t refs = 0); + virtual ~facet(); + facet(const facet&) = delete; + void operator=(const facet&) = delete; + }; +} +\end{codeblock} + +\pnum +Class \tcode{facet} is the base class for locale feature sets. +A class is a \defn{facet} +if it is publicly derived from another facet, or +if it is a class derived from \tcode{locale::facet} and +contains a publicly accessible declaration as follows: +\begin{footnote} +This is a complete list of requirements; there are no other requirements. +Thus, a facet class need not have a public +copy constructor, assignment, default constructor, destructor, etc. +\end{footnote} +\begin{codeblock} +static ::std::locale::id id; +\end{codeblock} + +\pnum +Template parameters in this Clause +which are required to be facets +are those named \tcode{Facet} in declarations. +A program that passes +a type that is \textit{not} a facet, or +a type that refers to a volatile-qualified facet, +as an (explicit or deduced) template parameter to +a locale function expecting a facet, +is ill-formed. +A const-qualified facet is a valid template argument to +any locale function that expects a \tcode{Facet} template parameter. + +\pnum +The \tcode{refs} argument to the constructor is used for lifetime management. +For \tcode{refs == 0}, +the implementation performs \tcode{delete static_cast(f)} +(where \tcode{f} is a point\-er to the facet) +when the last \tcode{locale} object containing the facet is destroyed; +for \tcode{refs == 1}, the implementation never destroys the facet. + +\pnum +Constructors of all facets defined in this Clause +take such an argument and pass it along to +their \tcode{facet} base class constructor. +All one-argument constructors defined in this Clause are \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 it returns \tcode{noconv}, +\tcode{internT} and \tcode{externT} are the same type, and +the converted sequence is identical to +the input sequence \range{from}{from\textunderscore\nobreak next}, +\tcode{to_next} is set equal to \tcode{to}, +the value of \tcode{state} is unchanged, and +there are no changes to the values in \range{to}{to_end}. + +\pnum +A \tcode{codecvt} facet +that is used by \tcode{basic_filebuf}\iref{file.streams} +shall have the property that if +\begin{codeblock} +do_out(state, from, from_end, from_next, to, to_end, to_next) +\end{codeblock} +would return \tcode{ok}, +where \tcode{from != from_end}, +then +\begin{codeblock} +do_out(state, from, from + 1, from_next, to, to_end, to_next) +\end{codeblock} +shall also return \tcode{ok}, +and that if +\begin{codeblock} +do_in(state, from, from_end, from_next, to, to_end, to_next) +\end{codeblock} +would return \tcode{ok}, +where \tcode{to != to_end}, +then +\begin{codeblock} +do_in(state, from, from_end, from_next, to, to + 1, to_next) +\end{codeblock} +shall also return \tcode{ok}. +\begin{footnote} +Informally, this means that \tcode{basic_filebuf} +assumes that the mappings from internal to external characters is 1 to N: +that a \tcode{codecvt} facet that is used by \tcode{basic_filebuf} +can translate characters one internal character at a time. +\end{footnote} +\begin{note} +As a result of operations on \tcode{state}, +it can return \tcode{ok} or \tcode{partial} and +set \tcode{from_next == from} and \tcode{to_next != to}. +\end{note} + +\pnum +\returns +An enumeration value, as summarized in \tref{locale.codecvt.inout}. + +\begin{floattable}{\tcode{do_in/do_out} result values}{locale.codecvt.inout} +{lp{3in}} +\topline +\lhdr{Value} & \rhdr{Meaning} \\ \capsep +\tcode{ok} & completed the conversion \\ +\tcode{partial} & not all source characters converted \\ +\tcode{error} & +encountered a character in \range{from}{from_end} +that cannot be converted \\ +\tcode{noconv} & +\tcode{internT} and \tcode{externT} are the same type, and input +sequence is identical to converted sequence \\ +\end{floattable} + +A return value of \tcode{partial}, +if \tcode{(from_next == from_end)}, +indicates +that either the destination sequence has not absorbed +all the available destination elements, or +that additional source elements are needed +before another destination element can be produced. + +\pnum +\remarks +Its operations on \tcode{state} are unspecified. +\begin{note} +This argument can be used, for example, +to maintain shift state, +to specify conversion options (such as count only), or +to identify a cache of seek offsets. +\end{note} +\end{itemdescr} + +\indexlibrarymember{codecvt}{do_unshift}% +\begin{itemdecl} +result do_unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{(to <= to_end)} is well-defined and \tcode{true}; +\tcode{state} is initialized, if at the beginning of a sequence, +or else is equal to the result of converting +the preceding characters in the sequence. + +\pnum +\effects +Places characters starting at \tcode{to} +that should be appended to terminate a sequence +when the current \tcode{stateT} is given by \tcode{state}. +\begin{footnote} +Typically these will be characters to return the state to \tcode{stateT()}. +\end{footnote} +Stores no more than \tcode{(to_end - to)} destination elements, and +leaves the \tcode{to_next} pointer +pointing one beyond the last element successfully stored. + +\pnum +\returns +An enumeration value, as summarized in \tref{locale.codecvt.unshift}. + +\begin{floattable}{\tcode{do_unshift} result values}{locale.codecvt.unshift} +{lp{.50\hsize}} +\topline +\lhdr{Value} & \rhdr{Meaning} \\ \capsep +\tcode{ok} & completed the sequence \\ +\tcode{partial} & +space for more than \tcode{to_end - to} destination elements was needed +to terminate a sequence given the value of \tcode{state}\\ +\tcode{error} & an unspecified error has occurred \\ +\tcode{noconv} & no termination is needed for this \tcode{state_type} \\ +\end{floattable} +\end{itemdescr} + +\indexlibrarymember{codecvt}{do_encoding}% +\begin{itemdecl} +int do_encoding() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{-1} if the encoding of the \tcode{externT} sequence is state-dependent; +else the constant number of \tcode{externT} characters +needed to produce an internal character; +or \tcode{0} if this number is not a constant. +\begin{footnote} +If \tcode{encoding()} yields \tcode{-1}, +then more than \tcode{max_length()} \tcode{externT} elements +can be consumed when producing a single \tcode{internT} character, and +additional \tcode{externT} elements can appear at the end of a sequence +after those that yield the final \tcode{internT} character. +\end{footnote} +\end{itemdescr} + +\indexlibrarymember{codecvt}{do_always_noconv}% +\begin{itemdecl} +bool do_always_noconv() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{do_in()} and \tcode{do_out()} return \tcode{noconv} +for all valid argument values. +\tcode{codecvt} returns \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{codecvt}{do_length}% +\begin{itemdecl} +int do_length(stateT& state, const externT* from, const externT* from_end, size_t max) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{(from <= from_end)} is well-defined and \tcode{true}; +\tcode{state} is initialized, if at the beginning of a sequence, +or else is equal to the result of converting +the preceding characters in the sequence. + +\pnum +\effects +The effect on the \tcode{state} argument is as if +it called \tcode{do_in(state, from, from_end, from, to, to + max, to)} +for \tcode{to} pointing to a buffer of at least \tcode{max} elements. + +\pnum +\returns +\tcode{(from_next - from)} where +\tcode{from_next} is the largest value in the range \crange{from}{from_end} +such that the sequence of values in the range \range{from}{from_next} +represents +\tcode{max} or fewer valid complete characters of type \tcode{internT}. +The specialization \tcode{codecvt}, +returns the lesser of \tcode{max} and \tcode{(from_end - from)}. +\end{itemdescr} + +\indexlibrarymember{codecvt}{do_max_length}% +\begin{itemdecl} +int do_max_length() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The maximum value that \tcode{do_length(state, from, from_end, 1)} can return +for any valid range \range{from}{from_end} +and \tcode{stateT} value \tcode{state}. +The specialization \tcode{codecvt::do_max_length()} +returns 1. +\end{itemdescr} + +\rSec4[locale.codecvt.byname]{Class template \tcode{codecvt_byname}} + +\indexlibraryglobal{codecvt_byname}% +\begin{codeblock} +namespace std { + template + class codecvt_byname : public codecvt { + public: + explicit codecvt_byname(const char*, size_t refs = 0); + explicit codecvt_byname(const string&, size_t refs = 0); + + protected: + ~codecvt_byname(); + }; +} +\end{codeblock} + +\rSec3[category.numeric]{The numeric category} + +\rSec4[category.numeric.general]{General} + +\pnum +The classes \tcode{num_get<>} and \tcode{num_put<>} +handle numeric formatting and parsing. +Virtual functions are provided for several numeric types. +Implementations may (but are not required to) delegate +extraction of smaller types to extractors for larger types. +\begin{footnote} +Parsing \tcode{"-1"} correctly into, e.g., an \tcode{unsigned short} +requires that the corresponding member \tcode{get()} +at least extract the sign before delegating. +\end{footnote} + +\pnum +All specifications of member functions for \tcode{num_put} and \tcode{num_get} +in the subclauses of~\ref{category.numeric} only apply to +the specializations required in Tables~\ref{tab:locale.category.facets} +and~\ref{tab:locale.spec}\iref{locale.category}, namely +\tcode{num_get}, +\tcode{num_get}, +\tcode{num_get}, +\tcode{num_put}, +\tcode{num_put}, and +\tcode{num_put}. +These specializations refer to the \tcode{ios_base\&} argument for +formatting specifications\iref{locale.categories}, +and to its imbued locale for the \tcode{numpunct<>} facet to +identify all numeric punctuation preferences, +and also for the \tcode{ctype<>} facet to perform character classification. + +\pnum +Extractor and inserter members of the standard iostreams use +\tcode{num_get<>} and \tcode{num_put<>} member functions for +formatting and parsing +numeric values\iref{istream.formatted.reqmts,ostream.formatted.reqmts}. + +\rSec4[locale.num.get]{Class template \tcode{num_get}} + +\rSec5[locale.num.get.general]{General} + +\indexlibraryglobal{num_get}% +\begin{codeblock} +namespace std { + template> + class num_get : public locale::facet { + public: + using 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 \&\& !uppercase} & \tcode{\%f} \\ \rowsep +\tcode{floatfield == ios_base::fixed} & \tcode{\%F} \\ \rowsep +\tcode{floatfield == ios_base::scientific \&\& !uppercase} & \tcode{\%e} \\ \rowsep +\tcode{floatfield == ios_base::scientific} & \tcode{\%E} \\ \rowsep +\tcode{floatfield == (ios_base::fixed | ios_base::scientific) \&\& !uppercase} & \tcode{\%a} \\ \rowsep +\tcode{floatfield == (ios_base::fixed | ios_base::scientific)} & \tcode{\%A} \\ \rowsep +\tcode{!uppercase} & \tcode{\%g} \\ \rowsep +\textit{otherwise} & \tcode{\%G} \\ +\end{floattable} + +For conversions from an integral or floating-point type +a length modifier is added to the conversion specifier +as indicated in \tref{facet.num.put.length}. + +\begin{floattable}{Length modifier}{facet.num.put.length} +{lc} +\topline +\lhdr{Type} & \rhdr{Length modifier} \\ \capsep +\tcode{long} & \tcode{l} \\ \rowsep +\tcode{long long} & \tcode{ll} \\ \rowsep +\tcode{unsigned long} & \tcode{l} \\ \rowsep +\tcode{unsigned long long} & \tcode{ll} \\ \rowsep +\tcode{long double} & \tcode{L} \\ \rowsep +\textit{otherwise} & \textit{none} \\ +\end{floattable} + +The conversion specifier has the following optional additional qualifiers +prepended as indicated in \tref{facet.num.put.conv}. + +\begin{floattable}{Numeric conversions}{facet.num.put.conv} +{llc} +\topline +\lhdr{Type(s)} & \chdr{State} & \rhdr{\tcode{stdio} equivalent} \\ \capsep +an integral type & \tcode{showpos} & \tcode{+} \\ + & \tcode{showbase} & \tcode{\#} \\ \rowsep +a floating-point type & \tcode{showpos} & \tcode{+} \\ + & \tcode{showpoint} & \tcode{\#} \\ +\end{floattable} + +For conversion from a floating-point type, +if \tcode{floatfield != (ios_base::fixed | ios_base::\brk{}scientific)}, +\tcode{str.precision()} is specified as precision +in the conversion specification. +Otherwise, no precision is specified. + +For conversion from \tcode{void*} the specifier is \tcode{\%p}. + +The representations at the end of stage 1 consists of the \tcode{char}'s +that would be printed by a call of \tcode{printf(s, val)} +where \tcode{s} is the conversion specifier determined above. + +\stage{2} +Any character \tcode{c} other than a decimal point(.) is converted to +a \tcode{charT} via +\begin{codeblock} +use_facet>(loc).widen(c) +\end{codeblock} + +A local variable \tcode{punct} is initialized via +\begin{codeblock} +const numpunct& punct = use_facet>(loc); +\end{codeblock} + +For arithmetic types, +\tcode{punct.thousands_sep()} characters are inserted into +the sequence as determined by the value returned by \tcode{punct.do_grouping()} +using the method described in~\ref{facet.numpunct.virtuals}. + +Decimal point characters(.) are replaced by \tcode{punct.decimal_point()}. + +\stage{3} +A local variable is initialized as +\begin{codeblock} +fmtflags adjustfield = (flags & (ios_base::adjustfield)); +\end{codeblock} + +The location of any padding +\begin{footnote} +The conversion specification \tcode{\#o} generates a leading \tcode{0} +which is \textit{not} a padding character. +\end{footnote} +is determined according to \tref{facet.num.put.fill}. + +\begin{floattable}{Fill padding}{facet.num.put.fill} +{p{3in}l} +\topline +\lhdr{State} & \rhdr{Location} \\ \capsep +\tcode{adjustfield == ios_base::left} & pad after \\ \rowsep +\tcode{adjustfield == ios_base::right} & pad before \\ \rowsep +\tcode{adjustfield == internal} and a sign occurs in the representation + & pad after the sign \\ \rowsep +\tcode{adjustfield == internal} and representation after stage 1 +began with 0x or 0X & pad after x or X \\ \rowsep +\textit{otherwise} & pad before \\ +\end{floattable} + +If \tcode{str.width()} is nonzero and the number of \tcode{charT}'s +in the sequence after stage 2 is less than \tcode{str.\brk{}width()}, +then enough \tcode{fill} characters are added to the sequence +at the position indicated for padding +to bring the length of the sequence to \tcode{str.width()}. + +\tcode{str.width(0)} is called. + +\stage{4} +The sequence of \tcode{charT}'s at the end of stage 3 are output via +\begin{codeblock} +*out++ = c +\end{codeblock} +\end{description} +\end{itemdescr} + +\indexlibrarymember{do_put}{num_put}% +\begin{itemdecl} +iter_type do_put(iter_type out, ios_base& str, char_type fill, bool val) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{(str.flags() \& ios_base::boolalpha) == 0} +returns \tcode{do_put(out, str, fill,\\(int)val)}, +otherwise obtains a string \tcode{s} as if by +\begin{codeblock} +string_type s = + val ? use_facet>(loc).truename() + : use_facet>(loc).falsename(); +\end{codeblock} +and then inserts each character \tcode{c} of \tcode{s} into \tcode{out} +via \tcode{*out++ = c} +and returns \tcode{out}. +\end{itemdescr} + +\rSec3[facet.numpunct]{The numeric punctuation facet} + +\rSec4[locale.numpunct]{Class template \tcode{numpunct}} + +\rSec5[locale.numpunct.general]{General} + +\indexlibraryglobal{numpunct}% +\begin{codeblock} +namespace std { + template + class numpunct : public locale::facet { + public: + using 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} +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}% +\begin{codeblock} +namespace std { + struct lconv; + + char* setlocale(int category, const char* locale); + lconv* localeconv(); +} + +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ +#define @\libmacro{LC_ALL}@ @\seebelow@ +#define @\libmacro{LC_COLLATE}@ @\seebelow@ +#define @\libmacro{LC_CTYPE}@ @\seebelow@ +#define @\libmacro{LC_MONETARY}@ @\seebelow@ +#define @\libmacro{LC_NUMERIC}@ @\seebelow@ +#define @\libmacro{LC_TIME}@ @\seebelow@ +\end{codeblock} + +\pnum +The contents and meaning of the header \libheaderdef{clocale} +are the same as the C standard library header \libheader{locale.h}. + +\rSec3[clocale.data.races]{Data races} + +\pnum +Calls to the function \tcode{setlocale} +may introduce a data race\iref{res.on.data.races} +with other calls to \tcode{setlocale} or +with calls to the functions listed in \tref{setlocale.data.races}. + +\xrefc{7.11} + +\begin{floattable} +{Potential \tcode{setlocale} data races} +{setlocale.data.races} +{lllll} +\topline + +\tcode{fprintf} & +\tcode{isprint} & +\tcode{iswdigit} & +\tcode{localeconv} & +\tcode{tolower} \\ + +\tcode{fscanf} & +\tcode{ispunct} & +\tcode{iswgraph} & +\tcode{mblen} & +\tcode{toupper} \\ + +\tcode{isalnum} & +\tcode{isspace} & +\tcode{iswlower} & +\tcode{mbstowcs} & +\tcode{towlower} \\ + +\tcode{isalpha} & +\tcode{isupper} & +\tcode{iswprint} & +\tcode{mbtowc} & +\tcode{towupper} \\ + +\tcode{isblank} & +\tcode{iswalnum} & +\tcode{iswpunct} & +\tcode{setlocale} & +\tcode{wcscoll} \\ + +\tcode{iscntrl} & +\tcode{iswalpha} & +\tcode{iswspace} & +\tcode{strcoll} & +\tcode{wcstod} \\ + +\tcode{isdigit} & +\tcode{iswblank} & +\tcode{iswupper} & +\tcode{strerror} & +\tcode{wcstombs} \\ + +\tcode{isgraph} & +\tcode{iswcntrl} & +\tcode{iswxdigit} & +\tcode{strtod} & +\tcode{wcsxfrm} \\ + +\tcode{islower} & +\tcode{iswctype} & +\tcode{isxdigit} & +\tcode{strxfrm} & +\tcode{wctomb} \\ +\end{floattable} + +\rSec1[text.encoding]{Text encodings identification} + +\rSec2[text.encoding.syn]{Header \tcode{} synopsis} + +\indexheader{text_encoding}% +\begin{codeblock} +namespace std { + struct text_encoding; + + // \ref{text.encoding.hash}, hash support + template struct hash; + template<> struct hash; +} +\end{codeblock} + +\rSec2[text.encoding.class]{Class \tcode{text_encoding}} + +\rSec3[text.encoding.overview]{Overview} + +\pnum +The class \tcode{text_encoding} describes an interface +for accessing the IANA Character Sets registry\supercite{iana-charset}. + +\indexlibraryglobal{text_encoding}% +\begin{codeblock} +namespace std { + struct text_encoding { + static constexpr size_t 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; + + // \ref{text.encoding.aliases}, class \tcode{text_encoding::aliases_view} + struct aliases_view; + constexpr aliases_view aliases() const noexcept; + + friend constexpr bool operator==(const text_encoding& a, + const text_encoding& b) noexcept; + friend constexpr bool operator==(const text_encoding& encoding, id i) noexcept; + + static consteval text_encoding literal() noexcept; + static text_encoding environment(); + template static bool environment_is(); + + private: + id @\exposid{mib_}@ = id::unknown; // \expos + char @\exposid{name_}@[max_name_length + 1] = {0}; // \expos + static constexpr bool @\exposidnc{comp-name}@(string_view a, string_view b); // \expos + }; +} +\end{codeblock} + +\pnum +Class \tcode{text_encoding} is +a trivially copyable type\iref{term.trivially.copyable.type}. + +\rSec3[text.encoding.general]{General} + +\pnum +A \defnadj{registered character}{encoding} is +a character encoding scheme in the IANA Character Sets registry. +\begin{note} +The IANA Character Sets registry uses the term ``character sets'' +to refer to character encodings. +\end{note} +The primary name of a registered character encoding is +the name of that encoding specified in the IANA Character Sets registry. + +\pnum +The set of known registered character encodings contains +every registered character encoding +specified in the IANA Character Sets registry except for the following: +\begin{itemize} +\item NATS-DANO (33) +\item NATS-DANO-ADD (34) +\end{itemize} + +\pnum +Each known registered character encoding +is identified by an enumerator in \tcode{text_encoding::id}, and +has a set of zero or more \defnx{aliases}{encoding!registered character!alias}. + +\pnum +The set of aliases of a known registered character encoding is an +\impldef{set of aliases of a known registered character encoding} +superset of the aliases specified in the IANA Character Sets registry. +The set of aliases for US-ASCII includes ``ASCII''. +No two aliases or primary names of distinct registered character encodings +are equivalent when compared by \tcode{text_encoding::\exposid{comp-name}}. + +\pnum +How a \tcode{text_encoding} object +is determined to be representative of a character encoding scheme +implemented in the translation or execution environment is +\impldef{how \tcode{text_encoding} objects are +determined to be representative of a character encoding scheme}. + +\pnum +An object \tcode{e} of type \tcode{text_encoding} such that +\tcode{e.mib() == text_encoding::id::unknown} is \tcode{false} and +\tcode{e.mib() == text_encoding::id::other} is \tcode{false} +maintains the following invariants: +\begin{itemize} +\item \tcode{*e.name() == '\textbackslash 0'} is \tcode{false}, and +\item \tcode{e.mib() == text_encoding(e.name()).mib()} is \tcode{true}. +\end{itemize} + +\pnum +\recommended +\begin{itemize} +\item +Implementations should not consider registered encodings to be interchangeable. +\begin{example} +Shift_JIS and Windows-31J denote different encodings. +\end{example} +\item +Implementations should not use the name of a registered encoding +to describe another similar yet different non-registered encoding +unless there is a precedent on that implementation. +\begin{example} +Big5 +\end{example} +\end{itemize} + +\rSec3[text.encoding.members]{Members} + +\indexlibraryctor{text_encoding}% +\begin{itemdecl} +constexpr explicit text_encoding(string_view enc) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\begin{itemize} +\item +\tcode{enc} represents a string in the ordinary literal encoding +consisting only of elements of the basic character set\iref{lex.charset}. +\item +\tcode{enc.size() <= max_name_length} is \tcode{true}. +\item +\tcode{enc.contains('\textbackslash 0')} is \tcode{false}. +\end{itemize} + +\pnum +\ensures +\begin{itemize} +\item +If there exists a primary name or alias \tcode{a} +of a known registered character encoding such that +\tcode{\exposid{comp-name}(a, enc)} is \tcode{true}, +\exposid{mib_} has the value of the enumerator of \tcode{id} +associated with that registered character encoding. +Otherwise, \tcode{\exposid{mib_} == id::other} is \tcode{true}. +\item +\tcode{enc.compare(\exposid{name_}) == 0} is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\indexlibraryctor{text_encoding}% +\begin{itemdecl} +constexpr text_encoding(id i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i} has the value of one of the enumerators of \tcode{id}. + +\pnum +\ensures +\begin{itemize} +\item +\tcode{\exposid{mib_} == i} is \tcode{true}. +\item +If \tcode{(\exposid{mib_} == id::unknown || \exposid{mib_} == id::other)} +is \tcode{true}, +\tcode{strlen(\exposid{name_}) == 0} is \tcode{true}. +Otherwise, +\tcode{ranges::contains(aliases(), string_view(\exposid{name_}))} +is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{mib}{text_encoding}% +\begin{itemdecl} +constexpr id mib() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{mib_}. +\end{itemdescr} + +\indexlibrarymember{name}{text_encoding}% +\begin{itemdecl} +constexpr const char* name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\exposid{name_}. + +\pnum +\remarks +\tcode{name()} is an \ntbs{} and +accessing elements of \exposid{name_} +outside of the range \countedrange{name()}{strlen(name()) + 1} +is undefined behavior. +\end{itemdescr} + +\indexlibrarymember{aliases}{text_encoding}% +\begin{itemdecl} +constexpr aliases_view aliases() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +Let \tcode{r} denote an instance of \tcode{aliases_view}. +If \tcode{*this} represents a known registered character encoding, then: +\begin{itemize} +\item +\tcode{r.front()} is the primary name of the registered character encoding, +\item +\tcode{r} contains the aliases of the registered character encoding, and +\item +\tcode{r} does not contain duplicate values when compared with \tcode{strcmp}. +\end{itemize} +Otherwise, \tcode{r} is an empty range. + +\pnum +Each element in \tcode{r} +is a non-null, non-empty \ntbs{} encoded in the literal character encoding and +comprising only characters from the basic character set. + +\pnum +\returns +\tcode{r}. + +\pnum +\begin{note} +The order of aliases in \tcode{r} is unspecified. +\end{note} +\end{itemdescr} + +\indexlibrarymember{literal}{text_encoding}% +\begin{itemdecl} +static consteval text_encoding literal() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{CHAR_BIT == 8} is \tcode{true}. + +\pnum +\returns +A \tcode{text_encoding} object representing +the ordinary character literal encoding\iref{lex.charset}. +\end{itemdescr} + +\indexlibrarymember{environment}{text_encoding}% +\begin{itemdecl} +static text_encoding environment(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{CHAR_BIT == 8} is \tcode{true}. + +\pnum +\returns +A \tcode{text_encoding} object representing +the \impldef{character encoding scheme of the environment} +character encoding scheme of the environment. +On a POSIX implementation, this is the encoding scheme associated with +the POSIX locale denoted by the empty string \tcode{""}. + +\pnum +\begin{note} +This function is not affected by calls to \tcode{setlocale}. +\end{note} + +\pnum +\recommended +Implementations should return a value that is not affected by calls to +the POSIX function \tcode{setenv} and +other functions which can modify the environment\iref{support.runtime}. +\end{itemdescr} + +\indexlibrarymember{environment_is}{text_encoding}% +\begin{itemdecl} +template + static bool environment_is(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{CHAR_BIT == 8} is \tcode{true}. + +\pnum +\returns +\tcode{environment() == i}. +\end{itemdescr} + +\indexlibrarymember{\exposid{comp-name}}{text_encoding}% +\begin{itemdecl} +static constexpr bool @\exposid{comp-name}@(string_view a, string_view b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if the two strings \tcode{a} and \tcode{b} +encoded in the ordinary literal encoding +are equal, ignoring, from left-to-right, +\begin{itemize} +\item +all elements that are not digits or letters\iref{character.seq.general}, +\item +character case, and +\item +any sequence of one or more \tcode{0} characters +not immediately preceded by a numeric prefix, where +a numeric prefix is a sequence consisting of +a digit in the range \crange{1}{9} +optionally followed by one or more elements which are not digits or letters, +\end{itemize} +and \tcode{false} otherwise. + +\begin{note} +This comparison is identical to +the ``Charset Alias Matching'' algorithm +described in the Unicode Technical Standard 22\supercite{unicode-charmap}. +\end{note} + +\begin{example} +\begin{codeblock} +static_assert(@\exposid{comp-name}@("UTF-8", "utf8") == true); +static_assert(@\exposid{comp-name}@("u.t.f-008", "utf8") == true); +static_assert(@\exposid{comp-name}@("ut8", "utf8") == false); +static_assert(@\exposid{comp-name}@("utf-80", "utf8") == false); +\end{codeblock} +\end{example} +\end{itemdescr} + +\rSec3[text.encoding.cmp]{Comparison functions} + +\indexlibrarymember{operator==}{text_encoding}% +\begin{itemdecl} +friend constexpr bool operator==(const text_encoding& a, const text_encoding& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{a.\exposid{mib_} == id::other \&\& b.\exposid{mib_} == id::other} +is \tcode{true}, +then \tcode{\exposid{comp-name}(a.\exposid{name_},\linebreak{}b.\exposid{name_})}. +Otherwise, \tcode{a.\exposid{mib_} == b.\exposid{mib_}}. +\end{itemdescr} + +\indexlibrarymember{operator==}{text_encoding}% +\begin{itemdecl} +friend constexpr bool operator==(const text_encoding& encoding, id i) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{encoding.\exposid{mib_} == i}. + +\pnum +\remarks +This operator induces an equivalence relation on its arguments +if and only if \tcode{i != id::other} is \tcode{true}. +\end{itemdescr} + +\rSec3[text.encoding.aliases]{Class \tcode{text_encoding::aliases_view}} + +\indexlibrarymember{aliases_view}{text_encoding}% +\indexlibrarymember{begin}{text_encoding::aliases_view}% +\indexlibrarymember{end}{text_encoding::aliases_view}% +\begin{itemdecl} +struct text_encoding::aliases_view : ranges::view_interface { + constexpr @\impdefx{type of \tcode{text_encoding::aliases_view::begin()}}@ begin() const; + constexpr @\impdefx{type of \tcode{text_encoding::aliases_view::end()}}@ end() const; +}; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{text_encoding::aliases_view} models +\libconcept{copyable}, +\tcode{ranges::\libconcept{view}}, +\tcode{ranges::\libconcept{random_access_range}}, and +\tcode{ranges::\libconcept{borrowed_range}}. +\begin{note} +\tcode{text_encoding::aliases_view} is not required to satisfy +\tcode{ranges::}\libconcept{common_range}, +nor \libconcept{default_initializable}. +\end{note} + +\pnum +Both +\tcode{ranges::range_value_t} and +\tcode{ranges::range_reference_t} +denote \tcode{const char*}. + +\pnum +\tcode{ranges::iterator_t} +is a constexpr iterator\iref{iterator.requirements.general}. +\end{itemdescr} + +\rSec3[text.encoding.id]{Enumeration \tcode{text_encoding::id}} + +\indexlibrarymember{id}{text_encoding}% +\begin{codeblock} +namespace std { + enum class text_encoding::id : int_least32_t { + 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~\ref{format.string.std}. +\item +For chrono types +the \fmtgrammarterm{format-spec} +is interpreted as a \fmtgrammarterm{chrono-format-spec} +as described in~\ref{time.format}. +\item +For user-defined \tcode{formatter} specializations, +the behavior of the \tcode{parse} member function +determines how the \fmtgrammarterm{format-spec} +is interpreted. +\end{itemize} +\end{example} + +\rSec3[format.string.std]{Standard format specifiers} + +\pnum +Each \tcode{formatter} specialization +described in \ref{format.formatter.spec} +for fundamental and string types +interprets \fmtgrammarterm{format-spec} as a +\fmtgrammarterm{std-format-spec}. +\begin{note} +The format specification can be used to specify such details as +minimum field width, alignment, padding, and decimal precision. +Some of the formatting options +are only supported for arithmetic types. +\end{note} +The syntax of format specifications is as follows: + +\begin{ncbnf} +\fmtnontermdef{std-format-spec}\br + \opt{fill-and-align} \opt{sign} \opt{\terminal{\#}} \opt{\terminal{0}} \opt{width} \opt{precision} \opt{\terminal{L}} \opt{type} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{fill-and-align}\br + \opt{fill} align +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{fill}\br + \textnormal{any character other than \tcode{\{} or \tcode{\}}} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{align} \textnormal{one of}\br + \terminal{< > \caret} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{sign} \textnormal{one of}\br + \terminal{+ -} \textnormal{space} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{width}\br + positive-integer\br + \terminal{\{} \opt{arg-id} \terminal{\}} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{precision}\br + \terminal{.} nonnegative-integer\br + \terminal{.} \terminal{\{} \opt{arg-id} \terminal{\}} +\end{ncbnf} + +\begin{ncbnf} +\fmtnontermdef{type} \textnormal{one of}\br + \terminal{a A b B c d e E f F g G o p P s x X ?} +\end{ncbnf} + +\pnum +Field widths are specified in \defnadj{field width}{units}; +the number of column positions required to display a sequence of +characters in a terminal. +The \defnadj{minimum}{field width} +is the number of field width units a replacement field minimally requires of +the formatted sequence of characters produced for a format argument. +The \defnadj{estimated}{field width} is the number of field width units +that are required for the formatted sequence of characters +produced for a format argument independent of +the effects of the \fmtgrammarterm{width} option. +The \defnadj{padding}{width} is the greater of \tcode{0} and +the difference of the minimum field width and the estimated field width. + +\begin{note} +The POSIX \tcode{wcswidth} function is an example of a function that, +given a string, returns the number of column positions required by +a terminal to display the string. +\end{note} + +\pnum +The \defnadj{fill}{character} is the character denoted by +the \fmtgrammarterm{fill} option or, +if the \fmtgrammarterm{fill} option is absent, the space character. +For a format specification in UTF-8, UTF-16, or UTF-32, +the fill character corresponds to a single Unicode scalar value. +\begin{note} +The presence of a \fmtgrammarterm{fill} option +is signaled by the character following it, +which must be one of the alignment options. +If the second character of \fmtgrammarterm{std-format-spec} +is not a valid alignment option, +then it is assumed that +the \fmtgrammarterm{fill} and \fmtgrammarterm{align} options +are both absent. +\end{note} + +\pnum +The \fmtgrammarterm{align} option applies to all argument types. +The meaning of the various alignment options is as specified in \tref{format.align}. +\begin{example} +\begin{codeblock} +char c = 120; +string s0 = format("{:6}", 42); // value of \tcode{s0} is \tcode{"\ \ \ \ 42"} +string s1 = format("{:6}", 'x'); // value of \tcode{s1} is \tcode{"x\ \ \ \ \ "} +string s2 = format("{:*<6}", 'x'); // value of \tcode{s2} is \tcode{"x*****"} +string s3 = format("{:*>6}", 'x'); // value of \tcode{s3} is \tcode{"*****x"} +string s4 = format("{:*@\caret{}@6}", 'x'); // value of \tcode{s4} is \tcode{"**x***"} +string s5 = format("{:6d}", c); // value of \tcode{s5} is \tcode{"\ \ \ 120"} +string s6 = format("{:6}", true); // value of \tcode{s6} is \tcode{"true\ \ "} +string s7 = format("{:*<6.3}", "123456"); // value of \tcode{s7} is \tcode{"123***"} +string s8 = format("{:02}", 1234); // value of \tcode{s8} is \tcode{"1234"} +string s9 = format("{:*<}", "12"); // value of \tcode{s9} is \tcode{"12"} +string sA = format("{:*<6}", "12345678"); // value of \tcode{sA} is \tcode{"12345678"} +string sB = format("{:@\importexample[-2pt]{example_05}\kern0.75pt\caret{}@6}", "x"); // value of \tcode{sB} is \tcode{"\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}x\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"} +string sC = format("{:*@\caret{}@6}", "@\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt@"); // value of \tcode{sC} is \tcode{"\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"} +\end{codeblock} +\end{example} +\begin{note} +The \fmtgrammarterm{fill}, \fmtgrammarterm{align}, and \tcode{0} options +have no effect when the minimum field width +is not greater than the estimated field width +because padding width is \tcode{0} in that case. +Since fill characters are assumed to have a field width of \tcode{1}, +use of a character with a different field width can produce misaligned output. +The \importexample[-2pt]{example_05} (\unicode{1f921}{clown face}) character has a field width of \tcode{2}. +The examples above that include that character +illustrate the effect of the field width +when that character is used as a fill character +as opposed to when it is used as a formatting argument. +\end{note} + +\begin{floattable}{Meaning of \fmtgrammarterm{align} options}{format.align}{lp{.8\hsize}} +\topline +\lhdr{Option} & \rhdr{Meaning} \\ \rowsep +\tcode{<} & +Forces the formatted argument to be aligned to the start of the field +by inserting $n$ fill characters after the formatted argument +where $n$ is the padding width. +This is the default for +non-arithmetic non-pointer types, \tcode{charT}, and \tcode{bool}, +unless an integer presentation type is specified. +\\ \rowsep +% +\tcode{>} & +Forces the formatted argument to be aligned to the end of the field +by inserting $n$ fill characters before the formatted argument +where $n$ is the padding width. +This is the default for +arithmetic types other than \tcode{charT} and \tcode{bool}, +pointer types, +or when an integer presentation type is specified. +\\ \rowsep +% +\tcode{\caret} & +Forces the formatted argument to be centered within the field +by inserting +$\bigl\lfloor \frac{n}{2} \bigr\rfloor$ +fill characters before and +$\bigl\lceil \frac{n}{2} \bigr\rceil$ +fill characters after the formatted argument, where +$n$ is the padding width. +\\ +\end{floattable} + +\pnum +The \fmtgrammarterm{sign} option is only valid +for arithmetic types other than \tcode{charT} and \tcode{bool} +or when an integer presentation type is specified. +The meaning of the various options is as specified in \tref{format.sign}. + +\begin{floattable}{Meaning of \fmtgrammarterm{sign} options}{format.sign}{lp{.8\hsize}} +\topline +\lhdr{Option} & \rhdr{Meaning} \\ \rowsep +\tcode{+} & +Indicates that a sign should be used for both non-negative and negative +numbers. +The \tcode{+} sign is inserted before the output of \tcode{to_chars} for +non-negative numbers other than negative zero. +\begin{tailnote} +For negative numbers and negative zero +the output of \tcode{to_chars} will already contain the sign +so no additional transformation is performed. +\end{tailnote} +\\ \rowsep +% +\tcode{-} & +Indicates that a sign should be used for +negative numbers and negative zero only (this is the default behavior). +\\ \rowsep +% +space & +Indicates that a leading space should be used for +non-negative numbers other than negative zero, and +a minus sign for negative numbers and negative zero. +\\ +\end{floattable} + +\pnum +The \fmtgrammarterm{sign} option applies to floating-point infinity and NaN. +\begin{example} +\begin{codeblock} +double inf = numeric_limits::infinity(); +double nan = numeric_limits::quiet_NaN(); +string s0 = format("{0:},{0:+},{0:-},{0: }", 1); // value of \tcode{s0} is \tcode{"1,+1,1, 1"} +string s1 = format("{0:},{0:+},{0:-},{0: }", -1); // value of \tcode{s1} is \tcode{"-1,-1,-1,-1"} +string s2 = format("{0:},{0:+},{0:-},{0: }", inf); // value of \tcode{s2} is \tcode{"inf,+inf,inf, inf"} +string s3 = format("{0:},{0:+},{0:-},{0: }", nan); // value of \tcode{s3} is \tcode{"nan,+nan,nan, nan"} +\end{codeblock} +\end{example} + +\pnum +The \tcode{\#} option causes the +% FIXME: This is not a definition. +\defnx{alternate form}{alternate form!format string} +to be used for the conversion. +This option is valid for arithmetic types other than +\tcode{charT} and \tcode{bool} +or when an integer presentation type is specified, and not otherwise. +For integral types, +the alternate form inserts the +base prefix (if any) specified in \tref{format.type.int} +into the output after the sign character (possibly space) if there is one, or +before the output of \tcode{to_chars} otherwise. +For floating-point types, +the alternate form causes the result of the conversion of finite values +to always contain a decimal-point character, +even if no digits follow it. +% FIXME: This is a weird place for this part of the spec to appear. +Normally, a decimal-point character appears in the result of these +conversions only if a digit follows it. +In addition, for \tcode{g} and \tcode{G} conversions, +% FIXME: Are they normally? What does this even mean? Reach into to_chars and +% alter its behavior? +trailing zeros are not removed from the result. + +\pnum +The \tcode{0} option is valid for arithmetic types +other than \tcode{charT} and \tcode{bool}, pointer types, or +when an integer presentation type is specified. +For formatting arguments that have a value +other than an infinity or a NaN, +this option pads the formatted argument by +inserting the \tcode{0} character $n$ times +following the sign or base prefix indicators (if any) +where $n$ is \tcode{0} if the \fmtgrammarterm{align} option is present and +is the padding width otherwise. +\begin{example} +\begin{codeblock} +char c = 120; +string s1 = format("{:+06d}", c); // value of \tcode{s1} is \tcode{"+00120"} +string s2 = format("{:#06x}", 0xa); // value of \tcode{s2} is \tcode{"0x000a"} +string s3 = format("{:<06}", -42); // value of \tcode{s3} is \tcode{"-42\ \ \ "} (\tcode{0} has no effect) +string s4 = format("{:06}", inf); // value of \tcode{s4} is \tcode{"\ \ \ inf"} (\tcode{0} has no effect) +\end{codeblock} +\end{example} + +\pnum +The \fmtgrammarterm{width} option specifies the minimum field width. +If the \fmtgrammarterm{width} option is absent, +the minimum field width is \tcode{0}. + +\pnum +If \tcode{\{ \opt{\fmtgrammarterm{arg-id}} \}} is used in +a \fmtgrammarterm{width} or \fmtgrammarterm{precision} option, +the value of the corresponding formatting argument is used as the value of the option. +The option is valid only if the corresponding formatting argument is +of standard signed or unsigned integer type. +If its value is negative, +an exception of type \tcode{format_error} is thrown. + +\pnum +% FIXME: What if it's an arg-id? +If \fmtgrammarterm{positive-integer} is used in a +\fmtgrammarterm{width} option, the value of the \fmtgrammarterm{positive-integer} +is interpreted as a decimal integer and used as the value of the option. + +\pnum +For the purposes of width computation, +a string is assumed to be in +a locale-independent, +\impldef{encoding assumption for \tcode{format} width computation} encoding. +Implementations should use either UTF-8, UTF-16, or UTF-32, +on platforms capable of displaying Unicode text in a terminal. +\begin{note} +This is the case for Windows\textregistered{}-based +\begin{footnote} +Windows\textregistered\ is a registered trademark of Microsoft Corporation. +This information is given for the convenience of users of this document and +does not constitute an endorsement by ISO or IEC of this product. +\end{footnote} +and many POSIX-based operating systems. +\end{note} + +\pnum +For a sequence of characters in UTF-8, UTF-16, or UTF-32, +an implementation should use as its field width +the sum of the field widths of the first code point +of each extended grapheme cluster. +Extended grapheme clusters are defined by \UAX{29} of the Unicode Standard. +The following code points have a field width of 2: +\begin{itemize} +\item +any code point with the \tcode{East_Asian_Width="W"} or +\tcode{East_Asian_Width="F"} property as described by +\UAX{44} of the Unicode Standard +\item +\ucode{4dc0} -- \ucode{4dff} (Yijing Hexagram Symbols) +\item +\ucode{1f300} -- \ucode{1f5ff} (Miscellaneous Symbols and Pictographs) +\item +\ucode{1f900} -- \ucode{1f9ff} (Supplemental Symbols and Pictographs) +\end{itemize} +The field width of all other code points is 1. + +\pnum +For a sequence of characters in neither UTF-8, UTF-16, nor UTF-32, +the field width is unspecified. + +\pnum +The \fmtgrammarterm{precision} option is valid +for floating-point and string types. +For floating-point types, +the value of this option specifies the precision +to be used for the floating-point presentation type. +For string types, +this option specifies the longest prefix of the formatted argument +to be included in the replacement field such that +the field width of the prefix is no greater than the value of this option. + +\pnum +If \fmtgrammarterm{nonnegative-integer} is used in +a \fmtgrammarterm{precision} option, +the value of the decimal integer is used as the value of the option. + +\pnum +When the \tcode{L} option is used, the form used for the conversion is called +the \defnx{locale-specific form}{locale-specific form!format string}. +The \tcode{L} option is only valid for arithmetic types, and +its effect depends upon the type. +\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 +$\tcode{sizeof...(Ts)} \ge 1$. +The types in \tcode{Ts...} are unique. +Each type in \tcode{Ts...} is one of +\keyword{bool}, +\tcode{char_type}, +\keyword{int}, +\tcode{\keyword{unsigned} \keyword{int}}, +\tcode{\keyword{long} \keyword{long} \keyword{int}}, +\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}, +\keyword{float}, +\keyword{double}, +\tcode{\keyword{long} \keyword{double}}, +\tcode{\keyword{const} char_type*}, +\tcode{basic_string_view}, or +\tcode{\keyword{const} \keyword{void}*}. + +\pnum +\remarks +A call to this function is a core constant expression only if +\begin{itemize} +\item +\tcode{id < num_args_} is \tcode{true} and +\item +the type of the corresponding format argument +(after conversion to \tcode{basic_format_arg}) is one of the types in \tcode{Ts...}. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{check_dynamic_spec_integral}{basic_format_parse_context}% +\begin{itemdecl} +constexpr void check_dynamic_spec_integral(size_t id) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +check_dynamic_spec(id); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{check_dynamic_spec_string}{basic_format_parse_context}% +\begin{itemdecl} +constexpr void check_dynamic_spec_string(size_t id) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +check_dynamic_spec>(id); +\end{codeblock} +\end{itemdescr} + +\rSec3[format.context]{Class template \tcode{basic_format_context}} + +\indexlibraryglobal{basic_format_context}% +\indexlibrarymember{iterator}{basic_format_context}% +\indexlibrarymember{char_type}{basic_format_context}% +\indexlibrarymember{formatter_type}{basic_format_context}% +\begin{codeblock} +namespace std { + template + class basic_format_context { + basic_format_args args_; // \expos + Out out_; // \expos + + basic_format_context(const basic_format_context&) = delete; + basic_format_context& operator=(const basic_format_context&) = delete; + + public: + using iterator = Out; + using char_type = charT; + template using formatter_type = formatter; + + 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 an NTCTS\iref{defns.ntcts}. + +\pnum +\effects +Let \tcode{TD} be \tcode{remove_const_t}. +\begin{itemize} +\item +If \tcode{TD} is \tcode{bool} or \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: + constexpr explicit format_error(const string& what_arg); + constexpr explicit format_error(const char* what_arg); + }; +} +\end{codeblock} + +\pnum +The class \tcode{format_error} defines the type of objects thrown as +exceptions to report errors from the formatting library. + +\indexlibraryctor{format_error}% +\begin{itemdecl} +constexpr format_error(const string& what_arg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{strcmp(what(), what_arg.c_str()) == 0}. + +\indexlibraryctor{format_error}% +\end{itemdescr} +\begin{itemdecl} +constexpr format_error(const char* what_arg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{strcmp(what(), what_arg) == 0}. +\end{itemdescr} + +\rSec1[re]{Regular expressions library} +\indextext{regular expression|(} + +\rSec2[re.general]{General} + +\pnum +Subclause \ref{re} describes components that \Cpp{} programs may use to +perform operations involving regular expression matching and +searching. + +\pnum +The following subclauses describe a basic regular expression class template and its +traits that can handle char-like\iref{strings.general} template arguments, +two specializations of this class template that handle sequences of \tcode{char} and \keyword{wchar_t}, +a class template that holds the +result of a regular expression match, a series of algorithms that allow a character +sequence to be operated upon by a regular expression, +and two iterator types for +enumerating regular expression matches, as summarized in \tref{re.summary}. + +\begin{libsumtab}{Regular expressions library summary}{re.summary} +\ref{re.req} & Requirements & \\ \rowsep +\ref{re.const} & Constants & \tcode{} \\ +\ref{re.badexp} & Exception type & \\ +\ref{re.traits} & Traits & \\ +\ref{re.regex} & Regular expression template & \\ +\ref{re.submatch} & Submatches & \\ +\ref{re.results} & Match results & \\ +\ref{re.alg} & Algorithms & \\ +\ref{re.iter} & Iterators & \\ \rowsep +\ref{re.grammar} & Grammar & \\ +\end{libsumtab} + +\pnum +The ECMAScript Language Specification described in Standard Ecma-262 +is called \defn{ECMA-262} in this Clause. + +\rSec2[re.req]{Requirements} + +\pnum +This subclause defines requirements on classes representing regular +expression traits. +\begin{note} +The class template +\tcode{regex_traits}, defined in \ref{re.traits}, +meets these requirements. +\end{note} + +\pnum +The class template \tcode{basic_regex}, defined in +\ref{re.regex}, needs a set of related types and +functions to complete the definition of its semantics. These types +and functions are provided as a set of member \grammarterm{typedef-name}{s} and functions +in the template parameter \tcode{traits} used by the \tcode{basic_regex} class +template. This subclause defines the semantics of these +members. + +\pnum +To specialize class template \tcode{basic_regex} for a character +container \tcode{CharT} and its related regular +expression traits class \tcode{Traits}, use \tcode{basic_regex}. + +\pnum +\indextext{regular expression traits!requirements}% +\indextext{requirements!regular expression traits}% +\indextext{regular expression!requirements}% +\indextext{locale}% +In the following requirements, +\begin{itemize} +\item +\tcode{X} denotes a traits class defining types and functions +for the character container type \tcode{charT}; +\item +\tcode{u} is an object of type \tcode{X}; +\item +\tcode{v} is an object of type \tcode{const X}; +\item +\tcode{p} is a value of type \tcode{const charT*}; +\item +\tcode{I1} and \tcode{I2} are input iterators\iref{input.iterators}; +\item +\tcode{F1} and \tcode{F2} are forward iterators\iref{forward.iterators}; +\item +\tcode{c} is a value of type \tcode{const charT}; +\item +\tcode{s} is an object of type \tcode{X::string_type}; +\item +\tcode{cs} is an object of type \tcode{const X::string_type}; +\item +\tcode{b} is a value of type \tcode{bool}; +\item +\tcode{I} is a value of type \tcode{int}; +\item +\tcode{cl} is an object of type \tcode{X::char_class_type}; and +\item +\tcode{loc} is an object of type \tcode{X::locale_type}. +\end{itemize} + +\pnum +A traits class \tcode{X} meets the regular expression traits requirements +if the following types and expressions are well-formed and have the specified +semantics. + +\begin{itemdecl} +typename X::char_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{charT}, +the character container type used in the implementation of class +template \tcode{basic_regex}. +\end{itemdescr} + +\begin{itemdecl} +typename X::string_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{basic_string} +\end{itemdescr} + +\begin{itemdecl} +typename X::locale_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A copy constructible type +that represents the locale used by the traits class. +\end{itemdescr} + +\begin{itemdecl} +typename X::char_class_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A bitmask type\iref{bitmask.types} +representing a particular character classification. +\end{itemdescr} + +\begin{itemdecl} +X::length(p) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_t} + +\pnum +\returns +The smallest \tcode{i} such that \tcode{p[i] == 0}. + +\pnum +\complexity +Linear in \tcode{i}. +\end{itemdescr} + +\begin{itemdecl} +v.translate(c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::char_type} + +\pnum +\returns +A character such that for any character \tcode{d} +that is to be considered equivalent to \tcode{c} +then \tcode{v.translate(c) == v.translate(d)}. +\end{itemdescr} + +\begin{itemdecl} +v.translate_nocase(c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::char_type} + +\pnum +\returns +For all characters \tcode{C} that are to be considered equivalent to \tcode{c} +when comparisons are to be performed without regard to case, +then \tcode{v.translate_nocase(c) == v.translate_nocase(C)}. +\end{itemdescr} + +\begin{itemdecl} +v.transform(F1, F2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::string_type} + +\pnum +\returns +A sort key for the character sequence designated by +the iterator range \range{F1}{F2} such that +if the character sequence \range{G1}{G2} sorts before +the character sequence \range{H1}{H2} +then \tcode{v.transform(G1, G2) < v.transform(H1, H2)}. +\end{itemdescr} + +\begin{itemdecl} +v.transform_primary(F1, F2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\indextext{regular expression traits!\idxcode{transform_primary}}% +\indextext{transform_primary@\tcode{transform_primary}!regular expression traits}% +\result +\tcode{X::string_type} + +\pnum +\returns +A sort key for the character sequence designated by +the iterator range \range{F1}{F2} such that +if the character sequence \range{G1}{G2} sorts before +the character sequence \range{H1}{H2} +when character case is not considered +then \tcode{v.transform_primary(G1, G2) < v.transform_primary(H1, H2)}. +\end{itemdescr} + +\begin{itemdecl} +v.lookup_collatename(F1, F2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::string_type} + +\pnum +\returns +A sequence of characters that represents the collating element +consisting of the character sequence designated by +the iterator range \range{F1}{F2}. +Returns an empty string +if the character sequence is not a valid collating element. +\end{itemdescr} + +\begin{itemdecl} +v.lookup_classname(F1, F2, b) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::char_class_type} + +\pnum +\returns +Converts the character sequence designated by the iterator range +\range{F1}{F2} into a value of a bitmask type that can +subsequently be passed to \tcode{isctype}. +Values returned from \tcode{lookup_classname} can be bitwise \logop{or}'ed together; +the resulting value represents membership +in either of the corresponding character classes. +If \tcode{b} is \tcode{true}, the returned bitmask is suitable for +matching characters without regard to their case. +Returns \tcode{0} +if the character sequence is not the name of +a character class recognized by \tcode{X}. +The value returned shall be independent of +the case of the characters in the sequence. +\end{itemdescr} + +\begin{itemdecl} +v.isctype(c, cl) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +Returns \tcode{true} if character \tcode{c} is a member of +one of the character classes designated by \tcode{cl}, +\tcode{false} otherwise. +\end{itemdescr} + +\begin{itemdecl} +v.value(c, I) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{int} + +\pnum +\returns +Returns the value represented by the digit \textit{c} in base +\textit{I} if the character \textit{c} is a valid digit in base \textit{I}; +otherwise returns \tcode{-1}. +\begin{note} +The value of \textit{I} will only be 8, 10, or 16. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +u.imbue(loc) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::locale_type} + +\indextext{locale}% +\pnum +\effects +Imbues \tcode{u} with the locale \tcode{loc} and +returns the previous locale used by \tcode{u} if any. +\end{itemdescr} + +\begin{itemdecl} +v.getloc() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::locale_type} + +\pnum +\returns +Returns the current locale used by \tcode{v}, if any. \indextext{locale}% +\end{itemdescr} + +\pnum +\begin{note} +Class template \tcode{regex_traits} meets the requirements for a +regular expression traits class when it is specialized for +\tcode{char} or \keyword{wchar_t}. This class template is described in +the header \libheader{regex}, and is described in \ref{re.traits}. +\end{note} + +\rSec2[re.syn]{Header \tcode{} synopsis} + +\indexheader{regex}% +\indexlibraryglobal{basic_regex}% +\indexlibraryglobal{regex}% +\indexlibraryglobal{wregex}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{re.const}, regex constants + namespace regex_constants { + using syntax_option_type = @\placeholder{T1}@; + using match_flag_type = @\placeholder{T2}@; + using error_type = @\placeholder{T3}@; + } + + // \ref{re.badexp}, class \tcode{regex_error} + class regex_error; + + // \ref{re.traits}, class template \tcode{regex_traits} + template struct regex_traits; + + // \ref{re.regex}, class template \tcode{basic_regex} + template> class basic_regex; + + using regex = basic_regex; + using wregex = basic_regex; + + // \ref{re.regex.swap}, \tcode{basic_regex} swap + template + void swap(basic_regex& e1, basic_regex& e2); + + // \ref{re.submatch}, class template \tcode{sub_match} + template + class sub_match; + + using csub_match = sub_match; + using wcsub_match = sub_match; + using ssub_match = sub_match; + using wssub_match = sub_match; + + // \ref{re.submatch.op}, \tcode{sub_match} non-member operators + template + bool operator==(const sub_match& lhs, const sub_match& rhs); + template + auto operator<=>(const sub_match& lhs, const sub_match& rhs); + + template + bool operator==( + const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + template + auto operator<=>( + const sub_match& lhs, + const basic_string::value_type, ST, SA>& rhs); + + template + bool operator==(const sub_match& lhs, + const typename iterator_traits::value_type* rhs); + template + auto operator<=>(const sub_match& lhs, + const typename iterator_traits::value_type* rhs); + + template + bool operator==(const sub_match& lhs, + const typename iterator_traits::value_type& rhs); + template + auto operator<=>(const sub_match& lhs, + const typename iterator_traits::value_type& rhs); + + template + basic_ostream& + operator<<(basic_ostream& os, const sub_match& m); + + // \ref{re.results}, class template \tcode{match_results} + template>> + class match_results; + + using cmatch = match_results; + using wcmatch = match_results; + using smatch = match_results; + using wsmatch = match_results; + + // \tcode{match_results} comparisons + template + bool operator==(const match_results& m1, + const match_results& m2); + + // \ref{re.results.swap}, \tcode{match_results} swap + template + void swap(match_results& m1, + match_results& m2); + + // \ref{re.alg.match}, function template \tcode{regex_match} + template + bool regex_match(BidirectionalIterator first, BidirectionalIterator last, + match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_match(BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_match(const charT* str, match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_match(const basic_string& s, + match_results::const_iterator, + Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_match(const basic_string&&, + match_results::const_iterator, + Allocator>&, + const basic_regex&, + regex_constants::match_flag_type = regex_constants::match_default) = delete; + template + bool regex_match(const charT* str, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_match(const basic_string& s, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + + // \ref{re.alg.search}, function template \tcode{regex_search} + template + bool regex_search(BidirectionalIterator first, BidirectionalIterator last, + match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(const charT* str, + match_results& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(const charT* str, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(const basic_string& s, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(const basic_string& s, + match_results::const_iterator, + Allocator>& m, + const basic_regex& e, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + bool regex_search(const basic_string&&, + match_results::const_iterator, + Allocator>&, + const basic_regex&, + regex_constants::match_flag_type + = regex_constants::match_default) = delete; + + // \ref{re.alg.replace}, function template \tcode{regex_replace} + template + OutputIterator + regex_replace(OutputIterator out, + BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + OutputIterator + regex_replace(OutputIterator out, + BidirectionalIterator first, BidirectionalIterator last, + const basic_regex& e, + const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + basic_string + regex_replace(const basic_string& s, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + basic_string + regex_replace(const basic_string& s, + const basic_regex& e, + const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + basic_string + regex_replace(const charT* s, + const basic_regex& e, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + template + basic_string + regex_replace(const charT* s, + const basic_regex& e, + const charT* fmt, + regex_constants::match_flag_type flags = regex_constants::match_default); + + // \ref{re.regiter}, class template \tcode{regex_iterator} + template::value_type, + class traits = regex_traits> + class regex_iterator; + + using cregex_iterator = regex_iterator; + using wcregex_iterator = regex_iterator; + using sregex_iterator = regex_iterator; + using wsregex_iterator = regex_iterator; + + // \ref{re.tokiter}, class template \tcode{regex_token_iterator} + template::value_type, + class traits = regex_traits> + class regex_token_iterator; + + using cregex_token_iterator = regex_token_iterator; + using wcregex_token_iterator = regex_token_iterator; + using sregex_token_iterator = regex_token_iterator; + using wsregex_token_iterator = regex_token_iterator; + + namespace pmr { + template + using match_results = + std::match_results>>; + + using cmatch = match_results; + using wcmatch = match_results; + using smatch = match_results; + using wsmatch = match_results; + } +} +\end{codeblock} + +\rSec2[re.const]{Namespace \tcode{std::regex_constants}} + +\rSec3[re.const.general]{General} + +\pnum +\indexlibraryglobal{regex_constants}% +The namespace \tcode{std::regex_constants} holds +symbolic constants used by the regular expression library. This +namespace provides three types, \tcode{syntax_option_type}, +\tcode{match_flag_type}, and \tcode{error_type}, along with several +constants of these types. + +\rSec3[re.synopt]{Bitmask type \tcode{syntax_option_type}} +\indexlibraryglobal{syntax_option_type}% +\indexlibrarymember{regex_constants}{syntax_option_type}% +\begin{codeblock} +namespace std::regex_constants { + using syntax_option_type = @\textit{T1}@; + inline constexpr syntax_option_type icase = @\unspec@; + inline constexpr syntax_option_type nosubs = @\unspec@; + inline constexpr syntax_option_type optimize = @\unspec@; + inline constexpr syntax_option_type collate = @\unspec@; + inline constexpr syntax_option_type ECMAScript = @\unspec@; + inline constexpr syntax_option_type basic = @\unspec@; + inline constexpr syntax_option_type extended = @\unspec@; + inline constexpr syntax_option_type awk = @\unspec@; + inline constexpr syntax_option_type grep = @\unspec@; + inline constexpr syntax_option_type egrep = @\unspec@; + inline constexpr syntax_option_type multiline = @\unspec@; +} +\end{codeblock} + +\pnum +\indexlibraryglobal{syntax_option_type}% +\indexlibrarymember{syntax_option_type}{icase}% +\indexlibrarymember{syntax_option_type}{nosubs}% +\indexlibrarymember{syntax_option_type}{optimize}% +\indexlibrarymember{syntax_option_type}{collate}% +\indexlibrarymember{syntax_option_type}{ECMAScript}% +\indexlibrarymember{syntax_option_type}{basic}% +\indexlibrarymember{syntax_option_type}{extended}% +\indexlibrarymember{syntax_option_type}{awk}% +\indexlibrarymember{syntax_option_type}{grep}% +\indexlibrarymember{syntax_option_type}{egrep}% +The type \tcode{syntax_option_type} is an \impldef{type of \tcode{syntax_option_type}} bitmask +type\iref{bitmask.types}. Setting its elements has the effects listed in +\tref{re.synopt}. A valid value of type +\tcode{syntax_option_type} shall have at most one of the grammar elements +\tcode{ECMAScript}, \tcode{basic}, \tcode{extended}, \tcode{awk}, \tcode{grep}, \tcode{egrep}, set. +If no grammar element is set, the default grammar is \tcode{ECMAScript}. + +\begin{libefftab} + {\tcode{syntax_option_type} effects} + {re.synopt} +% +\tcode{icase} & +Specifies that matching of regular expressions against a character +container sequence shall be performed without regard to case. +\indexlibrarymember{syntax_option_type}{icase}% +\\ \rowsep +% +\tcode{nosubs} & +Specifies that no sub-expressions shall be considered to be marked, so that +when a regular expression is matched against a +character container sequence, no sub-expression matches shall be +stored in the supplied \tcode{match_results} object. +\indexlibrarymember{syntax_option_type}{nosubs}% +\\ \rowsep +% +\tcode{optimize} & +Specifies that the regular expression engine should pay more attention +to the speed with which regular expressions are matched, and less to +the speed with which regular expression objects are +constructed. Otherwise it has no detectable effect on the program +output. +\indexlibrarymember{syntax_option_type}{optimize}% +\\ \rowsep +% +\tcode{collate} & +Specifies that character ranges of the form \tcode{"[a-b]"} shall be locale +sensitive.% +\indexlibrarymember{syntax_option_type}{collate}% +\indextext{locale}% +\\ \rowsep +% +\tcode{ECMAScript} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by ECMAScript in ECMA-262, as modified in~\ref{re.grammar}. +\newline \xref{ECMA-262 15.10} +\indextext{ECMAScript}% +\indexlibrarymember{syntax_option_type}{ECMAScript}% +\\ \rowsep +% +\tcode{basic} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by basic regular expressions in POSIX. +\newline \xref{POSIX, Base Definitions and Headers, Section 9.3} +\indextext{POSIX!regular expressions}% +\indexlibrarymember{syntax_option_type}{basic}% +\\ \rowsep +% +\tcode{extended} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by extended regular expressions in POSIX. +\newline \xref{POSIX, Base Definitions and Headers, Section 9.4} +\indextext{POSIX!extended regular expressions}% +\indexlibrarymember{syntax_option_type}{extended}% +\\ \rowsep +% +\tcode{awk} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by the utility awk in POSIX. +\indexlibrarymember{syntax_option_type}{awk}% +\\ \rowsep +% +\tcode{grep} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by the utility grep in POSIX. +\indexlibrarymember{syntax_option_type}{grep}% +\\ \rowsep +% +\tcode{egrep} & +Specifies that the grammar recognized by the regular expression engine +shall be that used by the utility grep when given the -E +option in POSIX. +\indexlibrarymember{syntax_option_type}{egrep}% +\\ \rowsep +% +\tcode{multiline} & +Specifies that \tcode{\caret} shall match the beginning of a line and +\tcode{\$} shall match the end of a line, +if the \tcode{ECMAScript} engine is selected. +\indexlibrarymember{syntax_option_type}{multiline}% +\\ +% +\end{libefftab} + +\rSec3[re.matchflag]{Bitmask type \tcode{match_flag_type}} + +\indexlibraryglobal{match_flag_type}% +\indexlibrarymember{regex_constants}{match_flag_type}% +\indexlibraryglobal{match_default}% +\indexlibraryglobal{match_not_bol}% +\indexlibraryglobal{match_not_eol}% +\indexlibraryglobal{match_not_bow}% +\indexlibraryglobal{match_not_eow}% +\indexlibraryglobal{match_any}% +\indexlibraryglobal{match_not_null}% +\indexlibraryglobal{match_continuous}% +\indexlibraryglobal{match_prev_avail}% +\indexlibraryglobal{format_default}% +\indexlibraryglobal{format_sed}% +\indexlibraryglobal{format_no_copy}% +\indexlibraryglobal{format_first_only}% +\begin{codeblock} +namespace std::regex_constants { + using match_flag_type = @\textit{T2}@; + inline constexpr match_flag_type match_default = {}; + inline constexpr match_flag_type match_not_bol = @\unspec@; + inline constexpr match_flag_type match_not_eol = @\unspec@; + inline constexpr match_flag_type match_not_bow = @\unspec@; + inline constexpr match_flag_type match_not_eow = @\unspec@; + inline constexpr match_flag_type match_any = @\unspec@; + inline constexpr match_flag_type match_not_null = @\unspec@; + inline constexpr match_flag_type match_continuous = @\unspec@; + inline constexpr match_flag_type match_prev_avail = @\unspec@; + inline constexpr match_flag_type format_default = {}; + inline constexpr match_flag_type format_sed = @\unspec@; + inline constexpr match_flag_type format_no_copy = @\unspec@; + inline constexpr match_flag_type format_first_only = @\unspec@; +} +\end{codeblock} + +\pnum +\indexlibraryglobal{match_flag_type}% +The type \tcode{match_flag_type} is an +\impldef{type of \tcode{regex_constants::match_flag_type}} bitmask type\iref{bitmask.types}. +The constants of that type, except for \tcode{match_default} and +\tcode{format_default}, are bitmask elements. The \tcode{match_default} and +\tcode{format_default} constants are empty bitmasks. +Matching a regular expression against a sequence of characters +\range{first}{last} proceeds according to the rules of the grammar specified for the regular +expression object, modified according to the effects listed in \tref{re.matchflag} for +any bitmask elements set. + +\begin{longlibefftab} + {\tcode{regex_constants::match_flag_type} effects} + {re.matchflag} +% +\indexlibraryglobal{match_not_bol}% +\tcode{match_not_bol} & +The first character in the sequence \range{first}{last} shall be treated +as though it is not at the beginning of a line, so the character +\verb|^| in the regular expression shall not match \range{first}{first}. +\\ \rowsep +% +\indexlibraryglobal{match_not_eol}% +\tcode{match_not_eol} & +The last character in the sequence \range{first}{last} shall be treated +as though it is not at the end of a line, so the character +\verb|"$"| in the regular expression shall not match \range{last}{last}. +\\ \rowsep +% +\indexlibraryglobal{match_not_bow}% +\tcode{match_not_bow} & +The expression \verb|"\\b"| shall not match the +sub-sequence \range{first}{first}. +\\ \rowsep +% +\indexlibraryglobal{match_not_eow}% +\tcode{match_not_eow} & +The expression \verb|"\\b"| shall not match the +sub-sequence \range{last}{last}. +\\ \rowsep +% +\indexlibraryglobal{match_any}% +\tcode{match_any} & +If more than one match is possible then any match is an +acceptable result. +\\ \rowsep +% +\indexlibraryglobal{match_not_null}% +\tcode{match_not_null} & +The expression shall not match an empty +sequence. +\\ \rowsep +% +\indexlibraryglobal{match_continuous}% +\tcode{match_continuous} & +The expression shall only match a sub-sequence that begins at +\tcode{first}. +\\ \rowsep +% +\indexlibraryglobal{match_prev_avail}% +\tcode{match_prev_avail} & +\verb!--first! is a valid iterator position. When this flag is +set the flags \tcode{match_not_bol} and \tcode{match_not_bow} shall be ignored by the +regular expression algorithms\iref{re.alg} and iterators\iref{re.iter}. +\\ \rowsep +% +\indexlibraryglobal{format_default}% +\tcode{format_default} & +When a regular expression match is to be replaced by a +new string, the new string shall be constructed using the rules used by +the ECMAScript replace function in ECMA-262, +part 15.5.4.11 String.prototype.replace. In +addition, during search and replace operations all non-overlapping +occurrences of the regular expression shall be located and replaced, and +sections of the input that did not match the expression shall be copied +unchanged to the output string. +\\ \rowsep +% +\indexlibraryglobal{format_sed}% +\tcode{format_sed} & +When a regular expression match is to be replaced by a +new string, the new string shall be constructed using the rules used by +the sed utility in POSIX. +\\ \rowsep +% +\indexlibraryglobal{format_no_copy}% +\tcode{format_no_copy} & +During a search and replace operation, sections of +the character container sequence being searched that do not match the +regular expression shall not be copied to the output string. \\ \rowsep +% +\indexlibraryglobal{format_first_only}% +\tcode{format_first_only} & +When specified during a search and replace operation, only the +first occurrence of the regular expression shall be replaced. +\\ +\end{longlibefftab} + +\rSec3[re.err]{Implementation-defined \tcode{error_type}} +\indexlibraryglobal{error_type}% +\indexlibrarymember{regex_constants}{error_type}% +\begin{codeblock} +namespace std::regex_constants { + using error_type = @\textit{T3}@; + inline constexpr error_type error_collate = @\unspec@; + inline constexpr error_type error_ctype = @\unspec@; + inline constexpr error_type error_escape = @\unspec@; + inline constexpr error_type error_backref = @\unspec@; + inline constexpr error_type error_brack = @\unspec@; + inline constexpr error_type error_paren = @\unspec@; + inline constexpr error_type error_brace = @\unspec@; + inline constexpr error_type error_badbrace = @\unspec@; + inline constexpr error_type error_range = @\unspec@; + inline constexpr error_type error_space = @\unspec@; + inline constexpr error_type error_badrepeat = @\unspec@; + inline constexpr error_type error_complexity = @\unspec@; + inline constexpr error_type error_stack = @\unspec@; +} +\end{codeblock} + +\pnum +\indexlibraryglobal{error_type}% +\indexlibrarymember{regex_constants}{error_type}% +The type \tcode{error_type} is an \impldef{type of +\tcode{regex_constants::error_type}} enumerated type\iref{enumerated.types}. +Values of type \tcode{error_type} represent the error +conditions described in \tref{re.err}: + +\begin{longliberrtab} + {\tcode{error_type} values in the C locale} + {re.err} +\tcode{error_collate} +& +The expression contains an invalid collating element name. \\ \rowsep +% +\tcode{error_ctype} +& +The expression contains an invalid character class name. \\ \rowsep +% +\tcode{error_escape} +& +The expression contains an invalid escaped character, or a trailing +escape. \\ \rowsep +% +\tcode{error_backref} +& +The expression contains an invalid back reference. \\ \rowsep +% +\tcode{error_brack} +& +The expression contains mismatched \verb|[| and \verb|]|. \\ \rowsep +% +\tcode{error_paren} +& +The expression contains mismatched \verb|(| and \verb|)|. \\ \rowsep +% +\tcode{error_brace} +& +The expression contains mismatched \verb|{| and \verb|}|. \\ \rowsep +% +\tcode{error_badbrace} +& +The expression contains an invalid range in a \verb|{}| expression. \\ +\rowsep +% +\tcode{error_range} +& +The expression contains an invalid character range, such as +\verb|[b-a]| in most encodings. \\ \rowsep +% +\tcode{error_space} +& +There is insufficient memory to convert the expression into a finite +state machine. \\ \rowsep +% +\tcode{error_badrepeat} +& +One of \verb|*?+{| is not preceded by a valid regular expression. \\ \rowsep +% +\tcode{error_complexity} +& +The complexity of an attempted match against a regular expression +exceeds a pre-set level. \\ \rowsep +% +\tcode{error_stack} +& +There is insufficient memory to determine whether the regular +expression matches the specified character sequence. \\ +% +\end{longliberrtab} + +\rSec2[re.badexp]{Class \tcode{regex_error}} +\indexlibraryglobal{regex_error}% +\begin{codeblock} +namespace std { + class regex_error : public runtime_error { + public: + explicit regex_error(regex_constants::error_type ecode); + regex_constants::error_type code() const; + }; +} +\end{codeblock} + +\pnum +The class \tcode{regex_error} defines the type of objects thrown as +exceptions to report errors from the regular expression library. + +\indexlibraryctor{regex_error}% +\begin{itemdecl} +regex_error(regex_constants::error_type ecode); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{ecode == code()}. +\end{itemdescr} + +\indexlibraryglobal{error_type}% +\indexlibrarymember{regex_constants}{error_type}% +\begin{itemdecl} +regex_constants::error_type code() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The error code that was passed to the constructor. +\end{itemdescr} + +\rSec2[re.traits]{Class template \tcode{regex_traits}} +\indexlibraryglobal{regex_traits}% +\begin{codeblock} +namespace std { + template + struct regex_traits { + using char_type = charT; + using string_type = basic_string; + using locale_type = locale; + using char_class_type = @\placeholdernc{bitmask_type}@; + + regex_traits(); + static size_t length(const char_type* p); + charT translate(charT c) const; + charT translate_nocase(charT c) const; + template + string_type transform(ForwardIterator first, ForwardIterator last) const; + template + string_type transform_primary( + ForwardIterator first, ForwardIterator last) const; + template + string_type lookup_collatename( + ForwardIterator first, ForwardIterator last) const; + template + char_class_type lookup_classname( + ForwardIterator first, ForwardIterator last, bool icase = false) const; + bool isctype(charT c, char_class_type f) const; + int value(charT ch, int radix) const; + locale_type imbue(locale_type l); + locale_type getloc() const; + }; +} +\end{codeblock} + +\pnum +\indextext{regular expression traits!requirements}% +\indextext{requirements!regular expression traits}% +The specializations \tcode{regex_traits} and +\tcode{regex_traits} meet the +requirements for a regular expression traits class\iref{re.req}. + +\indexlibrarymember{regex_traits}{char_class_type}% +\begin{itemdecl} +using char_class_type = @\textit{bitmask_type}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type \tcode{char_class_type} is used to represent a character +classification and is capable of holding an implementation specific +set returned by \tcode{lookup_classname}. +\end{itemdescr} + +\indexlibrarymember{length}{regex_traits}% +\begin{itemdecl} +static size_t length(const char_type* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{char_traits::length(p)}. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{translate}% +\begin{itemdecl} +charT translate(charT c) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{c}. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{translate_nocase}% +\begin{itemdecl} +charT translate_nocase(charT c) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{use_facet>(getloc()).tolower(c)}. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{transform}% +\begin{itemdecl} +template + string_type transform(ForwardIterator first, ForwardIterator last) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +string_type str(first, last); +return use_facet>( + getloc()).transform(str.data(), str.data() + str.length()); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{regex_traits}{transform_primary}% +\begin{itemdecl} +template + string_type transform_primary(ForwardIterator first, ForwardIterator last) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If +\begin{codeblock} +typeid(use_facet>(getloc())) == typeid(collate_byname) +\end{codeblock} +and the form of the sort key returned +by \tcode{collate_byname::transform(first, last)} is known and +can be converted into a primary sort key then returns that key, +otherwise returns an empty string. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{lookup_collatename}% +\begin{itemdecl} +template + string_type lookup_collatename(ForwardIterator first, ForwardIterator last) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A sequence of one or more characters that +represents the collating element consisting of the character +sequence designated by the iterator range \range{first}{last}. +Returns an empty string if the character sequence is not a +valid collating element. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{lookup_classname}% +\begin{itemdecl} +template + char_class_type lookup_classname( + ForwardIterator first, ForwardIterator last, bool icase = false) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An unspecified value that represents +the character classification named by the character sequence +designated by the iterator range \range{first}{last}. +If the parameter \tcode{icase} is \tcode{true} then the returned mask identifies the +character classification without regard to the case of the characters being +matched, otherwise it does honor the case of the characters being +matched. +\begin{footnote} +For example, if the parameter \tcode{icase} is \tcode{true} then +\tcode{[[:lower:]]} is the same as \tcode{[[:alpha:]]}. +\end{footnote} +The value +returned shall be independent of the case of the characters in +the character sequence. If the name +is not recognized then returns \tcode{char_class_type()}. + +\pnum +\remarks +For \tcode{regex_traits}, at least the narrow character names +in \tref{re.traits.classnames} shall be recognized. +For \tcode{regex_traits}, at least the wide character names +in \tref{re.traits.classnames} shall be recognized. +\end{itemdescr} + +\indexlibrarymember{regex_traits}{isctype}% +\begin{itemdecl} +bool isctype(charT c, char_class_type f) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Determines if the character \tcode{c} is a member of the character +classification represented by \tcode{f}. + +\pnum +\returns +Given the following function declaration: +\begin{codeblock} +// for exposition only +template + ctype_base::mask convert(typename regex_traits::char_class_type f); +\end{codeblock} +that returns a value in which each \tcode{ctype_base::mask} value corresponding to +a value in \tcode{f} named in \tref{re.traits.classnames} is set, then the +result is determined as if by: +\begin{codeblock} +ctype_base::mask m = convert(f); +const ctype& ct = use_facet>(getloc()); +if (ct.is(m, c)) { + return true; +} else if (c == ct.widen('_')) { + charT w[1] = { ct.widen('w') }; + char_class_type x = lookup_classname(w, w+1); + return (f&x) == x; +} else { + return false; +} +\end{codeblock} +\begin{example} +\begin{codeblock} +regex_traits t; +string d("d"); +string u("upper"); +regex_traits::char_class_type f; +f = t.lookup_classname(d.begin(), d.end()); +f |= t.lookup_classname(u.begin(), u.end()); +ctype_base::mask m = convert(f); // \tcode{m == ctype_base::digit | ctype_base::upper} +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +regex_traits t; +string w("w"); +regex_traits::char_class_type f; +f = t.lookup_classname(w.begin(), w.end()); +t.isctype('A', f); // returns \tcode{true} +t.isctype('_', f); // returns \tcode{true} +t.isctype(' ', f); // returns \tcode{false} +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{value}{regex_traits}% +\begin{itemdecl} +int value(charT ch, int radix) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The value of \tcode{radix} is 8, 10, or 16. + +\pnum +\returns +The value represented by the digit \tcode{ch} in base +\tcode{radix} if the character \tcode{ch} is a valid digit in base +\tcode{radix}; otherwise returns \tcode{-1}. +\end{itemdescr} + +\indexlibraryglobal{locale}% +\indexlibraryglobal{imbue}% +\begin{itemdecl} +locale_type imbue(locale_type loc); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Imbues \tcode{*this} with a copy of the +locale \tcode{loc}. +\begin{note} +Calling \tcode{imbue} with a +different locale than the one currently in use invalidates all cached +data held by \tcode{*this}. +\end{note} + +\pnum +\ensures +\tcode{getloc() == loc}. + +\pnum +\returns +If no locale has been previously imbued then a copy of the +global locale in effect at the time of construction of \tcode{*this}, +otherwise a copy of the last argument passed to \tcode{imbue}. +\end{itemdescr} + +\indexlibraryglobal{locale}% +\indexlibraryglobal{getloc}% +\begin{itemdecl} +locale_type getloc() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If no locale has been imbued then a copy of the global locale +in effect at the time of construction of \tcode{*this}, otherwise a copy of +the last argument passed to \tcode{imbue}. +\end{itemdescr} + +\begin{floattable}{Character class names and corresponding \tcode{ctype} masks}{re.traits.classnames}{lll} +\topline +\lhdr{Narrow character name} & \chdr{Wide character name} & \rhdr{Corresponding \tcode{ctype_base::mask} value} \\\capsep +\tcode{"alnum"} & \tcode{L"alnum"} & \tcode{ctype_base::alnum} \\ \rowsep +\tcode{"alpha"} & \tcode{L"alpha"} & \tcode{ctype_base::alpha} \\ \rowsep +\tcode{"blank"} & \tcode{L"blank"} & \tcode{ctype_base::blank} \\ \rowsep +\tcode{"cntrl"} & \tcode{L"cntrl"} & \tcode{ctype_base::cntrl} \\ \rowsep +\tcode{"digit"} & \tcode{L"digit"} & \tcode{ctype_base::digit} \\ \rowsep +\tcode{"d"} & \tcode{L"d"} & \tcode{ctype_base::digit} \\ \rowsep +\tcode{"graph"} & \tcode{L"graph"} & \tcode{ctype_base::graph} \\ \rowsep +\tcode{"lower"} & \tcode{L"lower"} & \tcode{ctype_base::lower} \\ \rowsep +\tcode{"print"} & \tcode{L"print"} & \tcode{ctype_base::print} \\ \rowsep +\tcode{"punct"} & \tcode{L"punct"} & \tcode{ctype_base::punct} \\ \rowsep +\tcode{"space"} & \tcode{L"space"} & \tcode{ctype_base::space} \\ \rowsep +\tcode{"s"} & \tcode{L"s"} & \tcode{ctype_base::space} \\ \rowsep +\tcode{"upper"} & \tcode{L"upper"} & \tcode{ctype_base::upper} \\ \rowsep +\tcode{"w"} & \tcode{L"w"} & \tcode{ctype_base::alnum} \\ \rowsep +\tcode{"xdigit"} & \tcode{L"xdigit"} & \tcode{ctype_base::xdigit} \\ +\end{floattable} + +\rSec2[re.regex]{Class template \tcode{basic_regex}} + +\rSec3[re.regex.general]{General} +\indexlibraryglobal{basic_regex}% + +\pnum +For a char-like type \tcode{charT}, specializations of class +template \tcode{basic_regex} represent regular expressions constructed +from character sequences of \tcode{charT} characters. In the rest +of~\ref{re.regex}, \tcode{charT} denotes a given char-like +type. Storage for a regular expression is allocated and freed as +necessary by the member functions of class \tcode{basic_regex}. + +\pnum +Objects of type specialization of \tcode{basic_regex} are responsible for +converting the sequence of \tcode{charT} objects to an internal +representation. It is not specified what form this representation +takes, nor how it is accessed by algorithms that operate on regular +expressions. +\begin{note} +Implementations will typically declare +some function templates as friends of \tcode{basic_regex} to achieve +this. +\end{note} + +\pnum +\indexlibraryglobal{regex_error}% +The functions described in \ref{re.regex} report errors by throwing +exceptions of type \tcode{regex_error}. + +\indexlibraryglobal{basic_regex}% +\begin{codeblock} +namespace std { + template> + class basic_regex { + public: + // types + using value_type = charT; + using traits_type = traits; + using string_type = 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 +\range{0}{match.size()} for which \tcode{match[i].matched} is \tcode{true}, +\tcode{match.position(i)} +shall return \tcode{distance(begin, match[i].\brk{}first)}. + +\pnum +\begin{note} +This means that \tcode{match.position(i)} gives the +offset from the beginning of the target sequence, which is often not +the same as the offset from the sequence passed in the call +to \tcode{regex_search}. +\end{note} + +\pnum +It is unspecified how the implementation makes these adjustments. + +\pnum +\begin{note} +This means that an implementation can call an +implementation-specific search function, in which case a program-defined +specialization of \tcode{regex_search} will not be +called. +\end{note} +\end{itemdescr} + +\indexlibrarymember{regex_iterator}{operator++}% +\begin{itemdecl} +regex_iterator operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +regex_iterator tmp = *this; +++(*this); +return tmp; +\end{codeblock} +\end{itemdescr} + +\rSec3[re.tokiter]{Class template \tcode{regex_token_iterator}} + +\rSec4[re.tokiter.general]{General} + +\pnum +\indexlibraryglobal{regex_token_iterator}% +The class template \tcode{regex_token_iterator} is an iterator adaptor; that +is to say it represents a new view of an existing iterator sequence, +by enumerating all the occurrences of a regular expression within that +sequence, and presenting one or more sub-expressions for each match +found. Each position enumerated by the iterator is a \tcode{sub_match} class +template instance that represents what matched a particular sub-expression +within the regular expression. + +\pnum +When class \tcode{regex_token_iterator} is used to enumerate a +single sub-expression with index $-1$ the iterator performs field +splitting: that is to say it enumerates one sub-expression for each section of +the character container sequence that does not match the regular +expression specified. + +\pnum +\indexlibraryglobal{match_results}% +After it is constructed, the iterator finds and stores a value +\tcode{regex_iterator position} +and sets the internal count \tcode{N} to zero. It also maintains a sequence +\tcode{subs} which contains a list of the sub-expressions which will be +enumerated. Every time \tcode{operator++} is used +the count \tcode{N} is incremented; if \tcode{N} exceeds or equals \tcode{subs.size()}, +then the iterator increments member \tcode{position} +and sets count \tcode{N} to zero. + +\pnum +If the end of sequence is reached (\tcode{position} is equal to the end of +sequence iterator), the iterator becomes equal to the end-of-sequence +iterator value, unless the sub-expression being enumerated has index $-1$, +in which case the iterator enumerates one last sub-expression that contains +all the characters from the end of the last regular expression match to the +end of the input sequence being enumerated, provided that this would not be an +empty sub-expression. + +\pnum +\indexlibrary{\idxcode{regex_token_iterator}!end-of-sequence}% +The default constructor constructs +an end-of-sequence iterator object, which is the only legitimate +iterator to be used for the end condition. The result of \tcode{operator*} on +an end-of-sequence iterator is not defined. For any other iterator value a +\tcode{const sub_match\&} is returned. +The result of \tcode{operator->} on an end-of-sequence iterator +is not defined. For any other iterator value a \tcode{const +sub_match*} is returned. + +\pnum +\indexlibrarymember{regex_token_iterator}{operator==}% +It is impossible to store things +into \tcode{regex_token_iterator}s. Two end-of-sequence iterators are always +equal. An end-of-sequence iterator is not equal to a +non-end-of-sequence iterator. Two non-end-of-sequence iterators are +equal when they are constructed from the same arguments. + +\begin{codeblock} +namespace std { + template::value_type, + class traits = regex_traits> + class regex_token_iterator { + public: + using regex_type = basic_regex; + using iterator_category = forward_iterator_tag; + using iterator_concept = input_iterator_tag; + using value_type = sub_match; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = const value_type&; + + regex_token_iterator(); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, + int submatch = 0, + regex_constants::match_flag_type m = + regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, + const vector& submatches, + regex_constants::match_flag_type m = + regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, + initializer_list submatches, + regex_constants::match_flag_type m = + regex_constants::match_default); + template + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type& re, + const int (&submatches)[N], + regex_constants::match_flag_type m = + regex_constants::match_default); + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, + int submatch = 0, + regex_constants::match_flag_type m = + regex_constants::match_default) = delete; + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, + const vector& submatches, + regex_constants::match_flag_type m = + regex_constants::match_default) = delete; + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, + initializer_list submatches, + regex_constants::match_flag_type m = + regex_constants::match_default) = delete; + template + regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, + const regex_type&& re, + const int (&submatches)[N], + regex_constants::match_flag_type m = + regex_constants::match_default) = delete; + regex_token_iterator(const regex_token_iterator&); + regex_token_iterator& operator=(const regex_token_iterator&); + bool operator==(const regex_token_iterator&) const; + bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } + const value_type& operator*() const; + const value_type* operator->() const; + regex_token_iterator& operator++(); + regex_token_iterator operator++(int); + + private: + using position_iterator = + regex_iterator; // \expos + position_iterator position; // \expos + const value_type* result; // \expos + value_type suffix; // \expos + size_t N; // \expos + vector subs; // \expos + }; +} +\end{codeblock} + +\pnum +A \textit{suffix iterator} is a \tcode{regex_token_iterator} object +that points to a final sequence of characters at +the end of the target sequence. In a suffix iterator the +member \tcode{result} holds a pointer to the data +member \tcode{suffix}, the value of the member \tcode{suffix.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}% +\begin{codeblock} +namespace std { + using wint_t = @\seebelow@; + using wctrans_t = @\seebelow@; + using wctype_t = @\seebelow@; + + int iswalnum(wint_t wc); + int iswalpha(wint_t wc); + int iswblank(wint_t wc); + int iswcntrl(wint_t wc); + int iswdigit(wint_t wc); + int iswgraph(wint_t wc); + int iswlower(wint_t wc); + int iswprint(wint_t wc); + int iswpunct(wint_t wc); + int iswspace(wint_t wc); + int iswupper(wint_t wc); + int iswxdigit(wint_t wc); + int iswctype(wint_t wc, wctype_t desc); + wctype_t wctype(const char* property); + wint_t towlower(wint_t wc); + wint_t towupper(wint_t wc); + wint_t towctrans(wint_t wc, wctrans_t desc); + wctrans_t wctrans(const char* property); +} + +#define @\libmacro{WEOF}@ @\seebelow@ +\end{codeblock} + +\pnum +The contents and meaning of the header \libheaderdef{cwctype} +are the same as the C standard library header \libheader{wctype.h}. + +\xrefc{7.30} + +\rSec2[cwchar.syn]{Header \tcode{} synopsis} + +\indexheader{cwchar}% +\indexlibraryglobal{btowc}% +\indexlibraryglobal{fgetwc}% +\indexlibraryglobal{fgetws}% +\indexlibraryglobal{fputwc}% +\indexlibraryglobal{fputws}% +\indexlibraryglobal{fwide}% +\indexlibraryglobal{fwprintf}% +\indexlibraryglobal{fwscanf}% +\indexlibraryglobal{getwchar}% +\indexlibraryglobal{getwc}% +\indexlibraryglobal{mbrlen}% +\indexlibraryglobal{mbrtowc}% +\indexlibraryglobal{mbsinit}% +\indexlibraryglobal{mbsrtowcs}% +\indexlibraryglobal{mbstate_t}% +\indexlibraryglobal{putwchar}% +\indexlibraryglobal{putwc}% +\indexlibraryglobal{size_t}% +\indexlibraryglobal{swprintf}% +\indexlibraryglobal{swscanf}% +\indexlibraryglobal{tm}% +\indexlibraryglobal{ungetwc}% +\indexlibraryglobal{vfwprintf}% +\indexlibraryglobal{vfwscanf}% +\indexlibraryglobal{vswprintf}% +\indexlibraryglobal{vswscanf}% +\indexlibraryglobal{vwprintf}% +\indexlibraryglobal{vwscanf}% +\indexlibraryglobal{wcrtomb}% +\indexlibraryglobal{wcscat}% +\indexlibraryglobal{wcschr}% +\indexlibraryglobal{wcscmp}% +\indexlibraryglobal{wcscoll}% +\indexlibraryglobal{wcscpy}% +\indexlibraryglobal{wcscspn}% +\indexlibraryglobal{wcsftime}% +\indexlibraryglobal{wcslen}% +\indexlibraryglobal{wcsncat}% +\indexlibraryglobal{wcsncmp}% +\indexlibraryglobal{wcsncpy}% +\indexlibraryglobal{wcspbrk}% +\indexlibraryglobal{wcsrchr}% +\indexlibraryglobal{wcsrtombs}% +\indexlibraryglobal{wcsspn}% +\indexlibraryglobal{wcsstr}% +\indexlibraryglobal{wcstod}% +\indexlibraryglobal{wcstof}% +\indexlibraryglobal{wcstok}% +\indexlibraryglobal{wcstold}% +\indexlibraryglobal{wcstoll}% +\indexlibraryglobal{wcstol}% +\indexlibraryglobal{wcstoull}% +\indexlibraryglobal{wcstoul}% +\indexlibraryglobal{wcsxfrm}% +\indexlibraryglobal{wctob}% +\indexlibraryglobal{wint_t}% +\indexlibraryglobal{wmemchr}% +\indexlibraryglobal{wmemcmp}% +\indexlibraryglobal{wmemcpy}% +\indexlibraryglobal{wmemmove}% +\indexlibraryglobal{wmemset}% +\indexlibraryglobal{wprintf}% +\indexlibraryglobal{wscanf}% +\begin{codeblock} +namespace std { + using size_t = @\textit{see \ref{support.types.layout}}@; // freestanding + using mbstate_t = @\seebelow@; // freestanding + using wint_t = @\seebelow@; // freestanding + + struct tm; + + int fwprintf(FILE* stream, const wchar_t* format, ...); + int fwscanf(FILE* stream, const wchar_t* format, ...); + int swprintf(wchar_t* s, size_t n, const wchar_t* format, ...); + int swscanf(const wchar_t* s, const wchar_t* format, ...); + int vfwprintf(FILE* stream, const wchar_t* format, va_list arg); + int vfwscanf(FILE* stream, const wchar_t* format, va_list arg); + int vswprintf(wchar_t* s, size_t n, const wchar_t* format, va_list arg); + int vswscanf(const wchar_t* s, const wchar_t* format, va_list arg); + int vwprintf(const wchar_t* format, va_list arg); + int vwscanf(const wchar_t* format, va_list arg); + int wprintf(const wchar_t* format, ...); + int wscanf(const wchar_t* format, ...); + wint_t fgetwc(FILE* stream); + wchar_t* fgetws(wchar_t* s, int n, FILE* stream); + wint_t fputwc(wchar_t c, FILE* stream); + int fputws(const wchar_t* s, FILE* stream); + int fwide(FILE* stream, int mode); + wint_t getwc(FILE* stream); + wint_t getwchar(); + wint_t putwc(wchar_t c, FILE* stream); + wint_t putwchar(wchar_t c); + wint_t ungetwc(wint_t c, FILE* stream); + double wcstod(const wchar_t* nptr, wchar_t** endptr); + float wcstof(const wchar_t* nptr, wchar_t** endptr); + long double wcstold(const wchar_t* nptr, wchar_t** endptr); + long int wcstol(const wchar_t* nptr, wchar_t** endptr, int base); + long long int wcstoll(const wchar_t* nptr, wchar_t** endptr, int base); + unsigned long int wcstoul(const wchar_t* nptr, wchar_t** endptr, int base); + unsigned long long int wcstoull(const wchar_t* nptr, wchar_t** endptr, int base); + wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2); // freestanding + wchar_t* wcsncpy(wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + wchar_t* wcscat(wchar_t* s1, const wchar_t* s2); // freestanding + wchar_t* wcsncat(wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + int wcscmp(const wchar_t* s1, const wchar_t* s2); // freestanding + int wcscoll(const wchar_t* s1, const wchar_t* s2); + int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + size_t wcsxfrm(wchar_t* s1, const wchar_t* s2, size_t n); + int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n); // freestanding + const wchar_t* wcschr(const wchar_t* s, wchar_t c); // freestanding; see \ref{library.c} + wchar_t* wcschr(wchar_t* s, wchar_t c); // freestanding; see \ref{library.c} + size_t wcscspn(const wchar_t* s1, const wchar_t* s2); // freestanding + const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2); // freestanding; see \ref{library.c} + wchar_t* wcspbrk(wchar_t* s1, const wchar_t* s2); // freestanding; see \ref{library.c} + const wchar_t* wcsrchr(const wchar_t* s, wchar_t c); // freestanding; see \ref{library.c} + wchar_t* wcsrchr(wchar_t* s, wchar_t c); // freestanding; see \ref{library.c} + size_t wcsspn(const wchar_t* s1, const wchar_t* s2); // freestanding + const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2); // freestanding; see \ref{library.c} + wchar_t* wcsstr(wchar_t* s1, const wchar_t* s2); // freestanding; see \ref{library.c} + wchar_t* wcstok(wchar_t* s1, const wchar_t* s2, wchar_t** ptr); // freestanding + const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n); // freestanding; see \ref{library.c} + wchar_t* wmemchr(wchar_t* s, wchar_t c, size_t n); // freestanding; see \ref{library.c} + size_t wcslen(const wchar_t* s); // freestanding + wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n); // freestanding + size_t wcsftime(wchar_t* s, size_t maxsize, const wchar_t* format, const tm* timeptr); + wint_t btowc(int c); + int wctob(wint_t c); + + // \ref{c.mb.wcs}, multibyte / wide string and character conversion functions + int mbsinit(const mbstate_t* ps); + size_t mbrlen(const char* s, size_t n, mbstate_t* ps); + size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps); + size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps); + size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps); + size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps); +} + +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ // freestanding +#define @\libmacro{WCHAR_MAX}@ @\seebelow@ // freestanding +#define @\libmacro{WCHAR_MIN}@ @\seebelow@ // freestanding +#define @\libmacro{WEOF}@ @\seebelow@ // freestanding +\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 \tcode{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 354a99f6ba..8d418aea34 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -169,7 +169,7 @@ \rSec2[thread.req.lockable]{Requirements for \oldconcept{Lockable} types} -\rSec3[thread.req.lockable.general]{In general} +\rSec3[thread.req.lockable.general]{General} \pnum An \defn{execution agent} is an entity such as a thread that may perform work in parallel with @@ -453,46 +453,80 @@ Such a request is called a \defn{stop request}. \pnum -\tcode{stop_source}, \tcode{stop_token}, and \tcode{stop_callback} -implement semantics of shared ownership of a \defn{stop state}. -Any \tcode{stop_source}, \tcode{stop_token}, or \tcode{stop_callback} -that shares ownership of the same stop state is an \defn{associated} -\tcode{stop_source}, \tcode{stop_token}, or \tcode{stop_callback}, respectively. -The last remaining owner of the stop state automatically -releases the resources associated with the stop state. - -\pnum -A \tcode{stop_token} can be passed to an operation which can either +The concepts +\exposconcept{stoppable-source}, +\libconcept{stoppable_token}, and +\exposconcept{stoppable-callback-for} +specify the required syntax and semantics of +shared access to a \defn{stop state}. +Any object modeling \exposconcept{stoppable-source}, +\libconcept{stoppable_token}, or +\exposconcept{stoppable-callback-for} +that refers to the same stop state is +an \defn{associated} +\exposconcept{stoppable-source}, +\libconcept{stoppable_token}, or +\exposconcept{stoppable-callback-for}, +respectively. + +\pnum +An object of a type that models \libconcept{stoppable_token} +can be passed to an operation that can either \begin{itemize} \item actively poll the token to check if there has been a stop request, or - \item register a callback using the \tcode{stop_callback} class template which + \item register a callback that will be called in the event that a stop request is made. \end{itemize} -A stop request made via a \tcode{stop_source} will be visible to all -associated \tcode{stop_token} and \tcode{stop_source} objects. +A stop request made via an object +whose type models \exposconcept{stoppable-source} +will be visible to +all associated \libconcept{stoppable_token} and +\exposconcept{stoppable-source} objects. Once a stop request has been made it cannot be withdrawn (a subsequent stop request has no effect). \pnum -Callbacks registered via a \tcode{stop_callback} object are called when -a stop request is first made by any associated \tcode{stop_source} object. +Callbacks registered via an object +whose type models \exposconcept{stoppable-callback-for} +are called when a stop request is first made +by any associated \exposconcept{stoppable-source} object. \pnum -Calls to the functions \tcode{request_stop}, \tcode{stop_requested}, -and \tcode{stop_possible} -do not introduce data races. -A call to \tcode{request_stop} that returns \tcode{true} -synchronizes with a call to \tcode{stop_requested} -on an associated \tcode{stop_token} or \tcode{stop_source} object -that returns \tcode{true}. -Registration of a callback synchronizes with the invocation of that callback. +The types \tcode{stop_source} and \tcode{stop_token} and +the class template \tcode{stop_callback} implement +the semantics of shared ownership of a stop state. +The last remaining owner of the stop state automatically releases +the resources associated with the stop state. +\pnum +An object of type \tcode{inplace_stop_source} +is the sole owner of its stop state. +An object of type \tcode{inplace_stop_token} or +of a specialization of the class template \tcode{inplace_stop_callback} +does not participate in ownership of its associated stop state. +\begin{note} +They are for use when all uses of the associated token and callback objects +are known to nest within the lifetime of the \tcode{inplace_stop_source} object. +\end{note} \rSec2[thread.stoptoken.syn]{Header \tcode{} synopsis} \indexheader{stop_token}% \begin{codeblock} namespace std { + // \ref{stoptoken.concepts}, stop token concepts + template + concept @\exposconcept{stoppable-callback-for}@ = @\seebelow@; // \expos + + template + concept @\libconcept{stoppable_token}@ = @\seebelow@; + + template + concept @\libconcept{unstoppable_token}@ = @\seebelow@; + + template + concept @\exposconcept{stoppable-source}@ = @\seebelow@; // \expos + // \ref{stoptoken}, class \tcode{stop_token} class stop_token; @@ -508,136 +542,322 @@ // \ref{stopcallback}, class template \tcode{stop_callback} template class stop_callback; -} -\end{codeblock} - - -\rSec2[stoptoken]{Class \tcode{stop_token}}% -\indexlibraryglobal{stop_token}% -\rSec3[stoptoken.general]{General} + // \ref{stoptoken.never}, class \tcode{never_stop_token} + class never_stop_token; -\pnum -\indexlibraryglobal{stop_token}% -The class \tcode{stop_token} provides an interface for querying whether -a stop request has been made (\tcode{stop_requested}) -or can ever be made (\tcode{stop_possible}) -using an associated \tcode{stop_source} object\iref{stopsource}. -A \tcode{stop_token} can also be passed to a -\tcode{stop_callback}\iref{stopcallback} constructor -to register a callback to be called when a stop request has been made -from an associated \tcode{stop_source}. + // \ref{stoptoken.inplace}, class \tcode{inplace_stop_token} + class inplace_stop_token; -\begin{codeblock} -namespace std { - class stop_token { - public: - // \ref{stoptoken.cons}, constructors, copy, and assignment - stop_token() noexcept; - - stop_token(const stop_token&) noexcept; - stop_token(stop_token&&) noexcept; - stop_token& operator=(const stop_token&) noexcept; - stop_token& operator=(stop_token&&) noexcept; - ~stop_token(); - void swap(stop_token&) noexcept; + // \ref{stopsource.inplace}, class \tcode{inplace_stop_source} + class inplace_stop_source; - // \ref{stoptoken.mem}, stop handling - [[nodiscard]] bool stop_requested() const noexcept; - [[nodiscard]] bool stop_possible() const noexcept; + // \ref{stopcallback.inplace}, class template \tcode{inplace_stop_callback} + template + class inplace_stop_callback; - [[nodiscard]] friend bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept; - friend void swap(stop_token& lhs, stop_token& rhs) noexcept; - }; + template + using stop_callback_for_t = T::template callback_type; } \end{codeblock} +\rSec2[stoptoken.concepts]{Stop token concepts} -\rSec3[stoptoken.cons]{Constructors, copy, and assignment} +\pnum +The exposition-only \exposconcept{stoppable-callback-for} concept +checks for a callback compatible with a given \tcode{Token} type. +\begin{codeblock} +template + concept @\defexposconcept{stoppable-callback-for}@ = // \expos + @\libconcept{invocable}@ && + @\libconcept{constructible_from}@ && + requires { typename stop_callback_for_t; } && + @\libconcept{constructible_from}@, const Token&, Initializer>; +\end{codeblock} -\indexlibraryctor{stop_token}% -\begin{itemdecl} -stop_token() noexcept; -\end{itemdecl} +\pnum +Let \tcode{t} and \tcode{u} be distinct, valid objects of type \tcode{Token} +that reference the same logical stop state; +let \tcode{init} be an expression such that +\tcode{\libconcept{same_as}} is \tcode{true}; and +let \tcode{SCB} denote the type \tcode{stop_callback_for_t}. -\begin{itemdescr} \pnum -\ensures -\tcode{stop_possible()} is \tcode{false} and -\tcode{stop_requested()} is \tcode{false}. +The concept +\tcode{\exposconcept{stoppable-callback-for}} +is modeled only if: +\begin{itemize} +\item +The following concepts are modeled: +\begin{itemize} +\item \tcode{\libconcept{constructible_from}} +\item \tcode{\libconcept{constructible_from}} +\item \tcode{\libconcept{constructible_from}} +\end{itemize} + +\item +An object of type \tcode{SCB} has +an associated callback function of type \tcode{CallbackFn}. +Let \tcode{scb} be an object of type \tcode{SCB} and +let \tcode{callback_fn} denote \tcode{scb's} associated callback function. +Direct-non-list-initializing \tcode{scb} from +arguments \tcode{t} and \tcode{init} +shall execute a \defnadj{stoppable callback}{registration} as follows: +\begin{itemize} +\item +If \tcode{t.stop_possible()} is \tcode{true}: +\begin{itemize} +\item +\tcode{callback_fn} shall be direct-initialized with \tcode{init}. +\item +Construction of \tcode{scb} shall only throw exceptions +thrown by the initialization of \tcode{callback_fn} from \tcode{init}. +\item +The callback invocation \tcode{std::forward(callback_fn)()} +shall be registered with \tcode{t}'s associated stop state as follows: +\begin{itemize} +\item +If \tcode{t.stop_requested()} evaluates to \tcode{false} +at the time of registration, +the callback invocation is added to the stop state's list of callbacks +such that \tcode{std::forward(\newline callback_fn)()} is evaluated +if a stop request is made on the stop state. +\item +Otherwise, \tcode{std::forward(callback_fn)()} +shall be immediately evaluated +on the thread executing \tcode{scb}'s constructor, and +the callback invocation shall not be added to the list of callback invocations. +\end{itemize} +If the callback invocation was added to stop state's list of callbacks, +\tcode{scb} shall be associated with the stop state. +\end{itemize} +\item \begin{note} -Because the created \tcode{stop_token} object can never receive a stop request, -no resources are allocated for a stop state. +If \tcode{t.stop_possible()} is \tcode{false}, +there is no requirement +that the initialization of \tcode{scb} +causes the initialization of \tcode{callback_fn}. \end{note} -\end{itemdescr} +\end{itemize} -\indexlibraryctor{stop_token}% -\begin{itemdecl} -stop_token(const stop_token& rhs) noexcept; -\end{itemdecl} +\item +Destruction of \tcode{scb} shall execute +a \defnadj{stoppable}{callback deregistration} as follows (in order): +\begin{itemize} +\item +If the constructor of \tcode{scb} did not register +a callback invocation with \tcode{t}'s stop state, +then the stoppable callback deregistration shall have no effect +other than destroying \tcode{callback_fn} if it was constructed. +\item +Otherwise, the invocation of \tcode{callback_fn} shall be removed +from the associated stop state. +\item +If \tcode{callback_fn} is concurrently executing on another thread, +then the stoppable callback deregistration shall block\iref{defns.block} +until the invocation of \tcode{callback_fn} returns +such that the return from the invocation of \tcode{callback_fn} +strongly happens before\iref{intro.races} +the destruction of \tcode{callback_fn}. +\item +If \tcode{callback_fn} is executing on the current thread, +then the destructor shall not block +waiting for the return from the invocation of \tcode{callback_fn}. +\item +A stoppable callback deregistration shall not block +on the completion of the invocation of some other callback +registered with the same logical stop state. +\item +The stoppable callback deregistration shall destroy \tcode{callback_fn}. +\end{itemize} +\end{itemize} -\begin{itemdescr} \pnum -\ensures -\tcode{*this == rhs} is \tcode{true}. -\begin{note} -\tcode{*this} and \tcode{rhs} share the ownership of the same stop state, -if any. -\end{note} -\end{itemdescr} +The \libconcept{stoppable_token} concept checks +for the basic interface of a stop token +that is copyable and allows polling to see if stop has been requested and +also whether a stop request is possible. +The \libconcept{unstoppable_token} concept checks +for a \libconcept{stoppable_token} type that does not allow stopping. +\begin{codeblock} +template class> + struct @\exposid{check-type-alias-exists}@; // \expos + +template + concept @\deflibconcept{stoppable_token}@ = + requires (const Token tok) { + typename @\exposid{check-type-alias-exists}@; + { tok.stop_requested() } noexcept -> @\libconcept{same_as}@; + { tok.stop_possible() } noexcept -> @\libconcept{same_as}@; + { Token(tok) } noexcept; // see implicit expression variations\iref{concepts.equality} + } && + @\libconcept{copyable}@ && + @\libconcept{equality_comparable}@; + +template + concept @\deflibconcept{unstoppable_token}@ = + @\libconcept{stoppable_token}@ && + requires (const Token tok) { + requires bool_constant<(!tok.stop_possible())>::value; + }; +\end{codeblock} -\indexlibraryctor{stop_token}% -\begin{itemdecl} -stop_token(stop_token&& rhs) noexcept; -\end{itemdecl} -\begin{itemdescr} \pnum -\ensures -\tcode{*this} contains the value of \tcode{rhs} -prior to the start of construction -and \tcode{rhs.stop_possible()} is \tcode{false}. -\end{itemdescr} +An object whose type models \libconcept{stoppable_token} +has at most one associated logical stop state. +A \libconcept{stoppable_token} object with no associated stop state +is said to be \defn{disengaged}. -\indexlibrarydtor{stop_token}% -\begin{itemdecl} -~stop_token(); -\end{itemdecl} +\pnum +Let \tcode{SP} be an evaluation of \tcode{t.stop_possible()} +that is \tcode{false}, and +let SR be an evaluation of \tcode{t.stop_requested()} that is \tcode{true}. -\begin{itemdescr} \pnum -\effects -Releases ownership of the stop state, if any. -\end{itemdescr} +The type \tcode{Token} models \libconcept{stoppable_token} only if: +\begin{itemize} +\item +Any evaluation of \tcode{u.stop_possible()} or \tcode{u.stop_requested()} +that happens after\iref{intro.races} \tcode{SP} is \tcode{false}. +\item +Any evaluation of \tcode{u.stop_possible()} or \tcode{u.stop_requested()} +that happens after \tcode{SR} is \tcode{true}. +\item +For any types \tcode{CallbackFn} and \tcode{Initializer} such that +\tcode{\exposconcept{stoppable-callback-for}} +is satisfied, +\tcode{\exposconcept{stoppable-callback-for}} +is modeled. +\item +If \tcode{t} is disengaged, +evaluations of \tcode{t.stop_possible()} and \tcode{t.stop_requested()} +are \tcode{false}. +\item +If \tcode{t} and \tcode{u} reference the same stop state, or +if both \tcode{t} and \tcode{u} are disengaged, +\tcode{t == u} is \tcode{true}; otherwise, it is \tcode{false}. +\end{itemize} -\indexlibrarymember{operator=}{stop_token}% -\begin{itemdecl} -stop_token& operator=(const stop_token& rhs) noexcept; -\end{itemdecl} +\pnum +An object +whose type models the exposition-only \exposconcept{stoppable-source} concept +can be queried +whether stop has been requested (\tcode{stop_requested}) and +whether stop is possible (\tcode{stop_possible}). +It is a factory for associated stop tokens (\tcode{get_token}), and +a stop request can be made on it (\tcode{request_stop}). +It maintains a list of registered stop callback invocations +that it executes when a stop request is first made. +\begin{codeblock} +template + concept @\defexposconcept{stoppable-source}@ = // \expos + requires (Source& src, const Source csrc) { // see implicit expression variations\iref{concepts.equality} + { csrc.get_token() } -> stoppable_token; + { csrc.stop_possible() } noexcept -> @\libconcept{same_as}@; + { csrc.stop_requested() } noexcept -> @\libconcept{same_as}@; + { src.request_stop() } -> @\libconcept{same_as}@; + }; +\end{codeblock} -\begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{stop_token(rhs).swap(*this)}. +An object whose type models \exposconcept{stoppable-source} has +at most one associated logical stop state. +If it has no associated stop state, it is said to be disengaged. +Let \tcode{s} be an object whose type models \exposconcept{stoppable-source} and +that is disengaged. +\tcode{s.stop_possible()} and \tcode{s.stop_requested()} shall be \tcode{false}. \pnum -\returns -\tcode{*this}. -\end{itemdescr} +Let \tcode{t} be an object whose type models \exposconcept{stoppable-source}. +If \tcode{t} is disengaged, +\tcode{t.get_token()} shall return a disengaged stop token; +otherwise, it shall return +a stop token that is associated with the stop state of \tcode{t}. -\indexlibrarymember{operator=}{stop_token}% -\begin{itemdecl} -stop_token& operator=(stop_token&& rhs) noexcept; -\end{itemdecl} +\pnum +Calls to the member functions +\tcode{request_stop}, \tcode{stop_requested}, and \tcode{stop_possible} and +similarly named member functions +on associated \libconcept{stoppable_token} objects +do not introduce data races. +A call to \tcode{request_stop} that returns \tcode{true} synchronizes with +a call to \tcode{stop_requested} on +an associated +\libconcept{stoppable_token} or \exposconcept{stoppable-source} object +that returns \tcode{true}. +Registration of a callback synchronizes with the invocation of that callback. -\begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{stop_token(std::move(rhs)).swap(*this)}. +If the \exposconcept{stoppable-source} is disengaged, +\tcode{request_stop} shall have no effect and return \tcode{false}. +Otherwise, it shall execute a \defnadj{stop request}{operation} +on the associated stop state. +A stop request operation determines +whether the stop state has received a stop request, and +if not, makes a stop request. +The determination and making of the stop request shall happen atomically, +as-if by a read-modify-write operation\iref{intro.races}. +If the request was made, +the stop state's registered callback invocations shall be +synchronously executed. +If an invocation of a callback exits via an exception +then \tcode{terminate} shall be invoked\iref{except.terminate}. +\begin{note} +No constraint is placed on the order +in which the callback invocations are executed. +\end{note} +\tcode{request_stop} shall return \tcode{true} if a stop request was made, and +\tcode{false} otherwise. +After a call to \tcode{request_stop} either +a call to \tcode{stop_possible} shall return \tcode{false} or +a call to \tcode{stop_requested} shall return \tcode{true}. +\begin{note} +A stop request includes notifying +all condition variables of type \tcode{condition_variable_any} +temporarily registered during +an interruptible wait\iref{thread.condvarany.intwait}. +\end{note} + +\rSec2[stoptoken]{Class \tcode{stop_token}}% +\indexlibraryglobal{stop_token}% + +\rSec3[stoptoken.general]{General} \pnum -\returns -\tcode{*this}. -\end{itemdescr} +\indexlibraryglobal{stop_token}% +The class \tcode{stop_token} models the concept \libconcept{stoppable_token}. +It shares ownership of its stop state, if any, +with its associated \tcode{stop_source} object\iref{stopsource} and +any \tcode{stop_token} objects to which it compares equal. + +\begin{codeblock} +namespace std { + class stop_token { + public: + template + using callback_type = stop_callback; + + stop_token() noexcept = default; + + // \ref{stoptoken.mem}, member functions + void swap(stop_token&) noexcept; + + bool stop_requested() const noexcept; + bool stop_possible() const noexcept; + + bool operator==(const stop_token& rhs) noexcept = default; + + private: + shared_ptr<@\unspec@> @\exposid{stop-state}@; // \expos + }; +} +\end{codeblock} + +\pnum +\exposid{stop-state} refers to the \tcode{stop_token}'s associated stop state. +A \tcode{stop_token} object is disengaged when \exposid{stop-state} is empty. + +\rSec3[stoptoken.mem]{Member functions} \indexlibrarymember{swap}{stop_token}% \begin{itemdecl} @@ -647,117 +867,82 @@ \begin{itemdescr} \pnum \effects -Exchanges the values of \tcode{*this} and \tcode{rhs}. +Equivalent to: +\begin{codeblock} +@\exposid{stop-state}@.swap(rhs.@\exposid{stop-state}@); +\end{codeblock} \end{itemdescr} -\rSec3[stoptoken.mem]{Members} - \indexlibrarymember{stop_requested}{stop_token}% \begin{itemdecl} -[[nodiscard]] bool stop_requested() const noexcept; +bool stop_requested() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{true} if \tcode{*this} has ownership of a stop state +\tcode{true} if \exposid{stop-state} refers to a stop state that has received a stop request; otherwise, \tcode{false}. \end{itemdescr} \indexlibrarymember{stop_possible}{stop_token}% \begin{itemdecl} -[[nodiscard]] bool stop_possible() const noexcept; +bool stop_possible() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{false} if: +\tcode{false} if \begin{itemize} -\item \tcode{*this} does not have ownership of a stop state, or +\item \tcode{*this} is disengaged, or \item a stop request was not made and there are no associated \tcode{stop_source} objects; \end{itemize} otherwise, \tcode{true}. \end{itemdescr} -\rSec3[stoptoken.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{stop_token}% -\begin{itemdecl} -[[nodiscard]] bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{true} if \tcode{lhs} and \tcode{rhs} have ownership of the same stop state -or if both \tcode{lhs} and \tcode{rhs} do not have ownership of a stop state; -otherwise \tcode{false}. -\end{itemdescr} - -\indexlibrarymember{swap}{stop_token}% -\begin{itemdecl} -friend void swap(stop_token& x, stop_token& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: \tcode{x.swap(y)}. -\end{itemdescr} - \rSec2[stopsource]{Class \tcode{stop_source}}% \indexlibraryglobal{stop_source}% \rSec3[stopsource.general]{General} -\pnum -\indexlibraryglobal{stop_source}% -The class \tcode{stop_source} implements the semantics of making a stop request. -A stop request made on a \tcode{stop_source} object is visible to all -associated \tcode{stop_source} and \tcode{stop_token}\iref{stoptoken} objects. -Once a stop request has been made it cannot be withdrawn -(a subsequent stop request has no effect). - -\indexlibraryglobal{nostopstate_t}% -\indexlibraryglobal{nostopstate}% - \begin{codeblock} namespace std { - // no-shared-stop-state indicator - struct nostopstate_t { - explicit nostopstate_t() = default; - }; - inline constexpr nostopstate_t nostopstate{}; - class stop_source { public: // \ref{stopsource.cons}, constructors, copy, and assignment stop_source(); - explicit stop_source(nostopstate_t) noexcept; + explicit stop_source(nostopstate_t) noexcept {} - stop_source(const stop_source&) noexcept; - stop_source(stop_source&&) noexcept; - stop_source& operator=(const stop_source&) noexcept; - stop_source& operator=(stop_source&&) noexcept; - ~stop_source(); + // \ref{stopsource.mem}, member functions void swap(stop_source&) noexcept; - // \ref{stopsource.mem}, stop handling - [[nodiscard]] stop_token get_token() const noexcept; - [[nodiscard]] bool stop_possible() const noexcept; - [[nodiscard]] bool stop_requested() const noexcept; + stop_token get_token() const noexcept; + bool stop_possible() const noexcept; + bool stop_requested() const noexcept; bool request_stop() noexcept; - [[nodiscard]] friend bool - operator==(const stop_source& lhs, const stop_source& rhs) noexcept; - friend void swap(stop_source& lhs, stop_source& rhs) noexcept; + bool operator==(const stop_source& rhs) noexcept = default; + + private: + shared_ptr<@\unspec@> @\exposid{stop-state}@; // \expos }; } \end{codeblock} +\pnum +\exposid{stop-state} refers to the \tcode{stop_source}'s associated stop state. +A \tcode{stop_source} object is disengaged when \exposid{stop-state} is empty. + +\pnum +\tcode{stop_source} models +\exposconcept{stoppable-source}, +\libconcept{copyable}, +\libconcept{equality_comparable}, and +\libconcept{swappable}. + \rSec3[stopsource.cons]{Constructors, copy, and assignment} \indexlibraryctor{stop_source}% @@ -768,7 +953,7 @@ \begin{itemdescr} \pnum \effects -Initialises \tcode{*this} to have ownership of a new stop state. +Initializes \exposid{stop-state} with a pointer to a new stop state. \pnum \ensures @@ -780,324 +965,439 @@ \tcode{bad_alloc} if memory cannot be allocated for the stop state. \end{itemdescr} -\indexlibraryctor{stop_source}% +\rSec3[stopsource.mem]{Member functions} + +\indexlibrarymember{swap}{stop_source}% \begin{itemdecl} -explicit stop_source(nostopstate_t) noexcept; +void swap(stop_source& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\ensures -\tcode{stop_possible()} is \tcode{false} and -\tcode{stop_requested()} is \tcode{false}. -\begin{note} -No resources are allocated for the state. -\end{note} +\effects +Equivalent to: +\begin{codeblock} +@\exposid{stop-state}@.swap(rhs.@\exposid{stop-state}@); +\end{codeblock} \end{itemdescr} -\indexlibraryctor{stop_source}% +\indexlibrarymember{get_token}{stop_source}% \begin{itemdecl} -stop_source(const stop_source& rhs) noexcept; +stop_token get_token() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\ensures -\tcode{*this == rhs} is \tcode{true}. -\begin{note} -\tcode{*this} and \tcode{rhs} share the ownership of the same stop state, -if any. -\end{note} +\returns +\tcode{stop_token()} if \tcode{stop_possible()} is \tcode{false}; +otherwise a new associated \tcode{stop_token} object; +i.e., its \exposid{stop-state} member is equal to +the \exposid{stop-state} member of \tcode{*this}. \end{itemdescr} -\indexlibraryctor{stop_source}% +\indexlibrarymember{stop_possible}{stop_source}% \begin{itemdecl} -stop_source(stop_source&& rhs) noexcept; +bool stop_possible() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\ensures -\tcode{*this} contains the value of \tcode{rhs} -prior to the start of construction -and \tcode{rhs.stop_possible()} is \tcode{false}. +\returns +\tcode{\exposidnc{stop-state} != nullptr}. \end{itemdescr} -\indexlibrarydtor{stop_source}% +\indexlibrarymember{stop_requested}{stop_source}% \begin{itemdecl} -~stop_source(); +bool stop_requested() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Releases ownership of the stop state, if any. +\returns +\tcode{true} if \exposid{stop-state} refers to a stop state +that has received a stop request; +otherwise, \tcode{false}. \end{itemdescr} -\indexlibrarymember{operator=}{stop_source}% +\indexlibrarymember{request_stop}{stop_source}% \begin{itemdecl} -stop_source& operator=(const stop_source& rhs) noexcept; +bool request_stop() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{stop_source(rhs).swap(*this)}. +Executes a stop request operation\iref{stoptoken.concepts} on +the associated stop state, if any. +\end{itemdescr} + +\rSec2[stopcallback]{Class template \tcode{stop_callback}}% +\indexlibraryglobal{stop_callback}% + +\rSec3[stopcallback.general]{General} \pnum -\returns -\tcode{*this}. -\end{itemdescr} +\indexlibraryglobal{stop_callback}% +\begin{codeblock} +namespace std { + template + class stop_callback { + public: + using callback_type = CallbackFn; + + // \ref{stopcallback.cons}, constructors and destructor + template + explicit stop_callback(const stop_token& st, Initializer&& init) + noexcept(is_nothrow_constructible_v); + template + explicit stop_callback(stop_token&& st, Initializer&& init) + noexcept(is_nothrow_constructible_v); + ~stop_callback(); + + stop_callback(const stop_callback&) = delete; + stop_callback(stop_callback&&) = delete; + stop_callback& operator=(const stop_callback&) = delete; + stop_callback& operator=(stop_callback&&) = delete; + + private: + CallbackFn @\exposid{callback-fn}@; // \expos + }; + + template + stop_callback(stop_token, CallbackFn) -> stop_callback; +} +\end{codeblock} -\indexlibrarymember{operator=}{stop_source}% +\pnum +\mandates +\tcode{stop_callback} is instantiated with an argument for the +template parameter \tcode{CallbackFn} +that satisfies both \libconcept{invocable} +and \libconcept{destructible}. + +\pnum +\remarks +For a type \tcode{Initializer}, +if +\tcode{\exposconcept{stoppable-callback-for}} +is satisfied, then +\tcode{\exposconcept{stoppable-callback-for}} is modeled. +The exposition-only \exposid{callback-fn} member is +the associated callback function\iref{stoptoken.concepts} of +\tcode{stop_callback<\newline CallbackFn>} objects. + +\rSec3[stopcallback.cons]{Constructors and destructor} + +\indexlibraryctor{stop_callback}% \begin{itemdecl} -stop_source& operator=(stop_source&& rhs) noexcept; +template + explicit stop_callback(const stop_token& st, Initializer&& init) + noexcept(is_nothrow_constructible_v); + +template + explicit stop_callback(stop_token&& st, Initializer&& init) + noexcept(is_nothrow_constructible_v); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: \tcode{stop_source(std::move(rhs)).swap(*this)}. +\constraints +\tcode{CallbackFn} and \tcode{Initializer} satisfy +\tcode{\libconcept{constructible_from}}. \pnum -\returns -\tcode{*this}. +\effects +Initializes \exposid{callback-fn} with \tcode{std::forward(init)} +and executes a stoppable callback registration\iref{stoptoken.concepts}. +If a callback is registered with \tcode{st}'s shared stop state, +then \tcode{*this} acquires shared ownership of that stop state. \end{itemdescr} -\indexlibrarymember{swap}{stop_source}% +\indexlibrarydtor{stop_callback}% \begin{itemdecl} -void swap(stop_source& rhs) noexcept; +~stop_callback(); \end{itemdecl} \begin{itemdescr} \pnum \effects -Exchanges the values of \tcode{*this} and \tcode{rhs}. +Executes a stoppable callback deregistration\iref{stoptoken.concepts} and +releases ownership of the stop state, if any. \end{itemdescr} -\rSec3[stopsource.mem]{Members} +\rSec2[stoptoken.never]{Class \tcode{never_stop_token}} + +\pnum +The class \tcode{never_stop_token} models +the \libconcept{unstoppable_token} concept. +It provides a stop token interface, +but also provides static information +that a stop is never possible nor requested. +\begin{codeblock} +namespace std { + class never_stop_token { + struct @\exposid{callback-type}@ { // \expos + explicit @\exposid{callback-type}@(never_stop_token, auto&&) noexcept {} + }; + public: + template + using callback_type = @\exposid{callback-type}@; + + static constexpr bool stop_requested() noexcept { return false; } + static constexpr bool stop_possible() noexcept { return false; } + + bool operator==(const never_stop_token&) const = default; + }; +} +\end{codeblock} + +\rSec2[stoptoken.inplace]{Class \tcode{inplace_stop_token}} + +\rSec3[stoptoken.inplace.general]{General} + +\pnum +The class \tcode{inplace_stop_token} models +the concept \libconcept{stoppable_token}. +It references the stop state of +its associated \tcode{inplace_stop_source} object\iref{stopsource.inplace}, +if any. +\begin{codeblock} +namespace std { + class inplace_stop_token { + public: + template + using callback_type = inplace_stop_callback; + + inplace_stop_token() = default; + bool operator==(const inplace_stop_token&) const = default; + + // \ref{stoptoken.inplace.mem}, member functions + bool stop_requested() const noexcept; + bool stop_possible() const noexcept; + void swap(inplace_stop_token&) noexcept; + + private: + const inplace_stop_source* @\exposid{stop-source}@ = nullptr; // \expos + }; +} +\end{codeblock} + +\rSec3[stoptoken.inplace.mem]{Member functions} -\indexlibrarymember{get_token}{stop_source sc}% \begin{itemdecl} -[[nodiscard]] stop_token get_token() const noexcept; +void swap(inplace_stop_token& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{stop_token()} if \tcode{stop_possible()} is \tcode{false}; -otherwise a new associated \tcode{stop_token} object. +\effects +Exchanges the values of \exposid{stop-source} and \tcode{rhs.\exposid{stop-source}}. \end{itemdescr} -\indexlibrarymember{stop_possible}{stop_source}% \begin{itemdecl} -[[nodiscard]] bool stop_possible() const noexcept; +bool stop_requested() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{true} if \tcode{*this} has ownership of a stop state; -otherwise, \tcode{false}. +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{stop-source}@ != nullptr && @\exposid{stop-source}@->stop_requested(); +\end{codeblock} + +\pnum +\begin{note} +As specified in \ref{basic.life}, +the behavior of \tcode{stop_requested} is undefined +unless the call strongly happens before the start of +the destructor of the associated \tcode{inplace_stop_source} object, if any. +\end{note} \end{itemdescr} -\indexlibrarymember{stop_requested}{stop_source}% \begin{itemdecl} -[[nodiscard]] bool stop_requested() const noexcept; +stop_possible() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{true} if \tcode{*this} has ownership of a stop state -that has received a stop request; -otherwise, \tcode{false}. +\tcode{\exposidnc{stop-source} != nullptr}. + +\pnum +\begin{note} +As specified in \ref{basic.stc.general}, +the behavior of \tcode{stop_possible} is implementation-defined +unless the call strongly happens before +the end of the storage duration of +the associated \tcode{inplace_stop_source} object, if any. +\end{note} \end{itemdescr} -\indexlibrarymember{request_stop}{stop_source}% +\rSec2[stopsource.inplace]{Class \tcode{inplace_stop_source}} + +\rSec3[stopsource.inplace.general]{General} + +\pnum +The class \tcode{inplace_stop_source} models \exposconcept{stoppable-source}. + +\begin{codeblock} +namespace std { + class inplace_stop_source { + public: + // \ref{stopsource.inplace.cons}, constructors + constexpr inplace_stop_source() noexcept; + + inplace_stop_source(inplace_stop_source&&) = delete; + inplace_stop_source(const inplace_stop_source&) = delete; + inplace_stop_source& operator=(inplace_stop_source&&) = delete; + inplace_stop_source& operator=(const inplace_stop_source&) = delete; + ~inplace_stop_source(); + + // \ref{stopsource.inplace.mem}, stop handling + constexpr inplace_stop_token get_token() const noexcept; + static constexpr bool stop_possible() noexcept { return true; } + bool stop_requested() const noexcept; + bool request_stop() noexcept; + }; +} +\end{codeblock} + +\rSec3[stopsource.inplace.cons]{Constructors} + \begin{itemdecl} -bool request_stop() noexcept; +constexpr inplace_stop_source() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -If \tcode{*this} does not have ownership of a stop state, returns \tcode{false}. -Otherwise, atomically determines whether the owned stop state -has received a stop request, -and if not, makes a stop request. -The determination and making of the stop request are an -atomic read-modify-write operation\iref{intro.races}. -If the request was made, -the callbacks registered by associated \tcode{stop_callback} objects -are synchronously called. -If an invocation of a callback exits via an exception -then \tcode{terminate} is invoked\iref{except.terminate}. -\begin{note} -A stop request includes notifying all condition variables -of type \tcode{condition_variable_any} -temporarily registered during -an interruptible wait\iref{thread.condvarany.intwait}. -\end{note} +Initializes a new stop state inside \tcode{*this}. \pnum \ensures -\tcode{stop_possible()} is \tcode{false} -or \tcode{stop_requested()} is \tcode{true}. +\tcode{stop_requested()} is \tcode{false}. +\end{itemdescr} + +\rSec3[stopsource.inplace.mem]{Member functions} + +\begin{itemdecl} +constexpr inplace_stop_token get_token() const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum \returns -\tcode{true} if this call made a stop request; -otherwise \tcode{false}. +A new associated \tcode{inplace_stop_token} object +whose \exposid{stop-source} member is equal to \tcode{this}. \end{itemdescr} -\rSec3[stopsource.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{stop_source}% \begin{itemdecl} -[[nodiscard]] friend bool - operator==(const stop_source& lhs, const stop_source& rhs) noexcept; +bool stop_requested() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{true} if \tcode{lhs} and \tcode{rhs} have ownership -of the same stop state -or if both \tcode{lhs} and \tcode{rhs} do not have ownership of a stop state; -otherwise \tcode{false}. +\tcode{true} if the stop state inside \tcode{*this} +has received a stop request; otherwise, \tcode{false}. \end{itemdescr} -\indexlibrarymember{swap}{stop_source}% \begin{itemdecl} -friend void swap(stop_source& x, stop_source& y) noexcept; +bool request_stop() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{x.swap(y)}. +Executes a stop request operation\iref{stoptoken.concepts}. + +\pnum +\ensures +\tcode{stop_requested()} is \tcode{true}. \end{itemdescr} -\rSec2[stopcallback]{Class template \tcode{stop_callback}}% -\indexlibraryglobal{stop_callback}% +\rSec2[stopcallback.inplace]{Class template \tcode{inplace_stop_callback}} -\rSec3[stopcallback.general]{General} +\rSec3[stopcallback.inplace.general]{General} -\pnum -\indexlibraryglobal{stop_callback}% \begin{codeblock} namespace std { - template - class stop_callback { + template + class inplace_stop_callback { public: - using callback_type = Callback; + using callback_type = CallbackFn; - // \ref{stopcallback.cons}, constructors and destructor - template - explicit stop_callback(const stop_token& st, C&& cb) - noexcept(is_nothrow_constructible_v); - template - explicit stop_callback(stop_token&& st, C&& cb) - noexcept(is_nothrow_constructible_v); - ~stop_callback(); + // \ref{stopcallback.inplace.cons}, constructors and destructor + template + explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init) + noexcept(is_nothrow_constructible_v); + ~inplace_stop_callback(); - stop_callback(const stop_callback&) = delete; - stop_callback(stop_callback&&) = delete; - stop_callback& operator=(const stop_callback&) = delete; - stop_callback& operator=(stop_callback&&) = delete; + inplace_stop_callback(inplace_stop_callback&&) = delete; + inplace_stop_callback(const inplace_stop_callback&) = delete; + inplace_stop_callback& operator=(inplace_stop_callback&&) = delete; + inplace_stop_callback& operator=(const inplace_stop_callback&) = delete; private: - Callback callback; // \expos + CallbackFn @\exposid{callback-fn}@; // \expos }; - template - stop_callback(stop_token, Callback) -> stop_callback; + template + inplace_stop_callback(inplace_stop_token, CallbackFn) + -> inplace_stop_callback; } \end{codeblock} \pnum \mandates -\tcode{stop_callback} is instantiated with an argument for the -template parameter \tcode{Callback} -that satisfies both \libconcept{invocable} -and \libconcept{destructible}. +\tcode{CallbackFn} satisfies both +\libconcept{invocable} and \libconcept{destructible}. \pnum -\expects -\tcode{stop_callback} is instantiated with an argument for the -template parameter \tcode{Callback} -that models both \libconcept{invocable} -and \libconcept{destructible}. - +\remarks +For a type \tcode{Initializer}, if +\begin{codeblock} +@\exposconcept{stoppable-callback-for}@ +\end{codeblock} +is satisfied, then +\begin{codeblock} +@\exposconcept{stoppable-callback-for}@ +\end{codeblock} +is modeled. +For an \tcode{inplace_stop_callback} object, +the exposition-only \exposid{callback-fn} member is +its associated callback function\iref{stoptoken.concepts}. -\rSec3[stopcallback.cons]{Constructors and destructor} +\rSec3[stopcallback.inplace.cons]{Constructors and destructor} -\indexlibraryctor{stop_callback}% \begin{itemdecl} -template -explicit stop_callback(const stop_token& st, C&& cb) - noexcept(is_nothrow_constructible_v); -template -explicit stop_callback(stop_token&& st, C&& cb) - noexcept(is_nothrow_constructible_v); +template + explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init) + noexcept(is_nothrow_constructible_v); \end{itemdecl} + \begin{itemdescr} \pnum \constraints -\tcode{Callback} and \tcode{C} satisfy \tcode{\libconcept{constructible_from}}. - -\pnum -\expects -\tcode{Callback} and \tcode{C} model \tcode{\libconcept{constructible_from}}. +\tcode{\libconcept{constructible_from}} is satisfied. \pnum \effects -Initializes \tcode{callback} with \tcode{std::forward(cb)}. -If \tcode{st.stop_requested()} is \tcode{true}, then -\tcode{std::forward(callback)()} -is evaluated in the current thread before the constructor returns. -Otherwise, if \tcode{st} has ownership of a stop state, -acquires shared ownership of that stop state and registers -the callback with that stop state -such that \tcode{std::forward(callback)()} -is evaluated by the first call to \tcode{request_stop()} -on an associated \tcode{stop_source}. - -\pnum -\throws -Any exception thrown by the initialization of \tcode{callback}. - -\pnum -\remarks -If evaluating -\tcode{std::forward(callback)()} -exits via an exception, -then \tcode{terminate} is invoked\iref{except.terminate}. +Initializes \exposid{callback-fn} with \tcode{std::forward(init)} +and executes a stoppable callback registration\iref{stoptoken.concepts}. \end{itemdescr} -\indexlibrarydtor{stop_callback}% \begin{itemdecl} -~stop_callback(); +~inplace_stop_callback(); \end{itemdecl} \begin{itemdescr} \pnum \effects -Unregisters the callback from the owned stop state, if any. -The destructor does not block waiting for the execution of another callback -registered by an associated \tcode{stop_callback}. -If \tcode{callback} is concurrently executing on another thread, -then the return from the invocation of \tcode{callback} -strongly happens before\iref{intro.races} -\tcode{callback} is destroyed. -If \tcode{callback} is executing on the current thread, -then the destructor does not block\iref{defns.block} waiting for -the return from the invocation of \tcode{callback}. -Releases ownership of the stop state, if any. +Executes a stoppable callback deregistration\iref{stoptoken.concepts}. \end{itemdescr} - \rSec1[thread.threads]{Threads} \rSec2[thread.threads.general]{General} @@ -1290,7 +1590,7 @@ \begin{itemdecl} template basic_ostream& - operator<< (basic_ostream& out, thread::id id); + operator<<(basic_ostream& out, thread::id id); \end{itemdecl} \begin{itemdescr} @@ -1650,22 +1950,22 @@ // \ref{thread.jthread.mem}, members void swap(jthread&) noexcept; - [[nodiscard]] bool joinable() const noexcept; + bool joinable() const noexcept; void join(); void detach(); - [[nodiscard]] id get_id() const noexcept; - [[nodiscard]] native_handle_type native_handle(); // see~\ref{thread.req.native} + id get_id() const noexcept; + native_handle_type native_handle(); // see~\ref{thread.req.native} // \ref{thread.jthread.stop}, stop token handling - [[nodiscard]] stop_source get_stop_source() noexcept; - [[nodiscard]] stop_token get_stop_token() const noexcept; + stop_source get_stop_source() noexcept; + stop_token get_stop_token() const noexcept; bool request_stop() noexcept; // \ref{thread.jthread.special}, specialized algorithms friend void swap(jthread& lhs, jthread& rhs) noexcept; // \ref{thread.jthread.static}, static members - [[nodiscard]] static unsigned int hardware_concurrency() noexcept; + static unsigned int hardware_concurrency() noexcept; private: stop_source ssource; // \expos @@ -1835,7 +2135,7 @@ \indexlibrarymember{joinable}{jthread}% \begin{itemdecl} -[[nodiscard]] bool joinable() const noexcept; +bool joinable() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -1934,7 +2234,7 @@ \indexlibrarymember{get_stop_source}{jthread}% \begin{itemdecl} -[[nodiscard]] stop_source get_stop_source() noexcept; +stop_source get_stop_source() noexcept; \end{itemdecl} \begin{itemdescr} @@ -1945,7 +2245,7 @@ \indexlibrarymember{get_stop_token}{jthread}% \begin{itemdecl} -[[nodiscard]] stop_token get_stop_token() const noexcept; +stop_token get_stop_token() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -1983,7 +2283,7 @@ \indexlibrarymember{hardware_concurrency}{jthread}% \begin{itemdecl} -[[nodiscard]] static unsigned int hardware_concurrency() noexcept; +static unsigned int hardware_concurrency() noexcept; \end{itemdecl} \begin{itemdescr} @@ -2097,28 +2397,24 @@ // \ref{atomics.order}, order and consistency enum class memory_order : @\unspecnc@; // freestanding inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; // freestanding - inline constexpr memory_order memory_order_consume = memory_order::consume; // freestanding inline constexpr memory_order memory_order_acquire = memory_order::acquire; // freestanding inline constexpr memory_order memory_order_release = memory_order::release; // freestanding inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; // freestanding inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; // freestanding - - template - T kill_dependency(T y) noexcept; // freestanding } // \ref{atomics.lockfree}, lock-free property -#define ATOMIC_BOOL_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_CHAR_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_CHAR8_T_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_CHAR16_T_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_CHAR32_T_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_WCHAR_T_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_SHORT_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_INT_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_LONG_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_LLONG_LOCK_FREE @\unspecnc@ // freestanding -#define ATOMIC_POINTER_LOCK_FREE @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_CHAR8_T_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\unspecnc@ // freestanding +#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\unspecnc@ // freestanding namespace std { // \ref{atomics.ref.generic}, class template \tcode{atomic_ref} @@ -2140,179 +2436,192 @@ void atomic_store(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - void atomic_store(atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr void atomic_store(atomic*, // freestanding + typename atomic::value_type) noexcept; template void atomic_store_explicit(volatile atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + typename atomic::value_type, memory_order) noexcept; template - void atomic_store_explicit(atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr void atomic_store_explicit(atomic*, // freestanding + typename atomic::value_type, memory_order) noexcept; template T atomic_load(const volatile atomic*) noexcept; // freestanding template - T atomic_load(const atomic*) noexcept; // freestanding + constexpr T atomic_load(const atomic*) noexcept; // freestanding template T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; // freestanding template - T atomic_load_explicit(const atomic*, memory_order) noexcept; // freestanding + constexpr T atomic_load_explicit(const atomic*, memory_order) noexcept; // freestanding template T atomic_exchange(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_exchange(atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr T atomic_exchange(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_exchange_explicit(volatile atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + typename atomic::value_type, memory_order) noexcept; template - T atomic_exchange_explicit(atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr T atomic_exchange_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template bool atomic_compare_exchange_weak(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_weak(atomic*, // freestanding - typename atomic::value_type*, - typename atomic::value_type) noexcept; + constexpr bool atomic_compare_exchange_weak(atomic*, // freestanding + typename atomic::value_type*, + typename atomic::value_type) noexcept; template bool atomic_compare_exchange_strong(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_strong(atomic*, // freestanding - typename atomic::value_type*, - typename atomic::value_type) noexcept; + constexpr bool atomic_compare_exchange_strong(atomic*, // freestanding + typename atomic::value_type*, + typename atomic::value_type) noexcept; template bool atomic_compare_exchange_weak_explicit(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_weak_explicit(atomic*, // freestanding - typename atomic::value_type*, - typename atomic::value_type, - memory_order, memory_order) noexcept; + constexpr bool atomic_compare_exchange_weak_explicit(atomic*, // freestanding + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; template bool atomic_compare_exchange_strong_explicit(volatile atomic*, // freestanding typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_strong_explicit(atomic*, // freestanding - typename atomic::value_type*, - typename atomic::value_type, - memory_order, memory_order) noexcept; + constexpr bool atomic_compare_exchange_strong_explicit(atomic*, // freestanding + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; template T atomic_fetch_add(volatile atomic*, // freestanding typename atomic::difference_type) noexcept; template - T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; // freestanding + constexpr T atomic_fetch_add(atomic*, // freestanding + typename atomic::difference_type) noexcept; template T atomic_fetch_add_explicit(volatile atomic*, // freestanding typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, // freestanding - memory_order) noexcept; + constexpr T atomic_fetch_add_explicit(atomic*, // freestanding + typename atomic::difference_type, + memory_order) noexcept; template T atomic_fetch_sub(volatile atomic*, // freestanding typename atomic::difference_type) noexcept; template - T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; // freestanding + constexpr T atomic_fetch_sub(atomic*, // freestanding + typename atomic::difference_type) noexcept; template T atomic_fetch_sub_explicit(volatile atomic*, // freestanding typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, // freestanding - memory_order) noexcept; + constexpr T atomic_fetch_sub_explicit(atomic*, // freestanding + typename atomic::difference_type, + memory_order) noexcept; template T atomic_fetch_and(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr T atomic_fetch_and(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_fetch_and_explicit(volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr T atomic_fetch_and_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template T atomic_fetch_or(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr T atomic_fetch_or(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_fetch_or_explicit(volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr T atomic_fetch_or_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template T atomic_fetch_xor(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr T atomic_fetch_xor(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_fetch_xor_explicit(volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr T atomic_fetch_xor_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template T atomic_fetch_max(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_fetch_max(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_max(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_fetch_max_explicit(volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_max_explicit(atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + constexpr T atomic_fetch_max_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template T atomic_fetch_min(volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - T atomic_fetch_min(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_min(atomic*, // freestanding + typename atomic::value_type) noexcept; template T atomic_fetch_min_explicit(volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_min_explicit(atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + constexpr T atomic_fetch_min_explicit(atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template void atomic_wait(const volatile atomic*, // freestanding typename atomic::value_type) noexcept; template - void atomic_wait(const atomic*, typename atomic::value_type) noexcept; // freestanding + constexpr void atomic_wait(const atomic*, // freestanding + typename atomic::value_type) noexcept; template void atomic_wait_explicit(const volatile atomic*, // freestanding typename atomic::value_type, memory_order) noexcept; template - void atomic_wait_explicit(const atomic*, typename atomic::value_type, // freestanding - memory_order) noexcept; + constexpr void atomic_wait_explicit(const atomic*, // freestanding + typename atomic::value_type, + memory_order) noexcept; template void atomic_notify_one(volatile atomic*) noexcept; // freestanding template - void atomic_notify_one(atomic*) noexcept; // freestanding + constexpr void atomic_notify_one(atomic*) noexcept; // freestanding template void atomic_notify_all(volatile atomic*) noexcept; // freestanding template - void atomic_notify_all(atomic*) noexcept; // freestanding + constexpr void atomic_notify_all(atomic*) noexcept; // freestanding // \ref{atomics.alias}, type aliases using atomic_bool = atomic; // freestanding @@ -2373,35 +2682,37 @@ struct atomic_flag; // freestanding bool atomic_flag_test(const volatile atomic_flag*) noexcept; // freestanding - bool atomic_flag_test(const atomic_flag*) noexcept; // freestanding + constexpr bool atomic_flag_test(const atomic_flag*) noexcept; // freestanding bool atomic_flag_test_explicit(const volatile atomic_flag*, // freestanding memory_order) noexcept; - bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept; // freestanding + constexpr bool atomic_flag_test_explicit(const atomic_flag*, // freestanding + memory_order) noexcept; bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; // freestanding - bool atomic_flag_test_and_set(atomic_flag*) noexcept; // freestanding + constexpr bool atomic_flag_test_and_set(atomic_flag*) noexcept; // freestanding bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, // freestanding memory_order) noexcept; - bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; // freestanding + constexpr bool atomic_flag_test_and_set_explicit(atomic_flag*, // freestanding + memory_order) noexcept; void atomic_flag_clear(volatile atomic_flag*) noexcept; // freestanding - void atomic_flag_clear(atomic_flag*) noexcept; // freestanding + constexpr void atomic_flag_clear(atomic_flag*) noexcept; // freestanding void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; // freestanding - void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; // freestanding + constexpr void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; // freestanding void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept; // freestanding - void atomic_flag_wait(const atomic_flag*, bool) noexcept; // freestanding + constexpr void atomic_flag_wait(const atomic_flag*, bool) noexcept; // freestanding void atomic_flag_wait_explicit(const volatile atomic_flag*, // freestanding bool, memory_order) noexcept; - void atomic_flag_wait_explicit(const atomic_flag*, // freestanding - bool, memory_order) noexcept; + constexpr void atomic_flag_wait_explicit(const atomic_flag*, // freestanding + bool, memory_order) noexcept; void atomic_flag_notify_one(volatile atomic_flag*) noexcept; // freestanding - void atomic_flag_notify_one(atomic_flag*) noexcept; // freestanding + constexpr void atomic_flag_notify_one(atomic_flag*) noexcept; // freestanding void atomic_flag_notify_all(volatile atomic_flag*) noexcept; // freestanding - void atomic_flag_notify_all(atomic_flag*) noexcept; // freestanding - #define ATOMIC_FLAG_INIT @\seebelownc@ // freestanding + constexpr void atomic_flag_notify_all(atomic_flag*) noexcept; // freestanding + #define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelownc@ // freestanding // \ref{atomics.fences}, fences - extern "C" void atomic_thread_fence(memory_order) noexcept; // freestanding - extern "C" void atomic_signal_fence(memory_order) noexcept; // freestanding + extern "C" constexpr void atomic_thread_fence(memory_order) noexcept; // freestanding + extern "C" constexpr void atomic_signal_fence(memory_order) noexcept; // freestanding } \end{codeblock} @@ -2480,13 +2791,11 @@ \rSec2[atomics.order]{Order and consistency} \indexlibraryglobal{memory_order}% \indexlibrarymember{relaxed}{memory_order}% -\indexlibrarymember{consume}{memory_order}% \indexlibrarymember{acquire}{memory_order}% \indexlibrarymember{release}{memory_order}% \indexlibrarymember{acq_rel}{memory_order}% \indexlibrarymember{seq_cst}{memory_order}% \indexlibraryglobal{memory_order_relaxed}% -\indexlibraryglobal{memory_order_consume}% \indexlibraryglobal{memory_order_acquire}% \indexlibraryglobal{memory_order_release}% \indexlibraryglobal{memory_order_acq_rel}% @@ -2495,7 +2804,7 @@ \begin{codeblock} namespace std { enum class memory_order : @\unspec@ { - relaxed, consume, acquire, release, acq_rel, seq_cst + relaxed = 0, acquire = 2, release = 3, acq_rel = 4, seq_cst = 5 }; } \end{codeblock} @@ -2513,15 +2822,6 @@ \tcode{memory_order::seq_cst}: a store operation performs a release operation on the affected memory location. -\item \tcode{memory_order::consume}: a load operation performs a consume operation on the -affected memory location. -\begin{note} -Prefer \tcode{memory_order::acquire}, which provides stronger guarantees -than \tcode{memory_order::consume}. Implementations have found it infeasible -to provide performance better than that of \tcode{memory_order::acquire}. -Specification revisions are under consideration. -\end{note} - \item \tcode{memory_order::acquire}, \tcode{memory_order::acq_rel}, and \tcode{memory_order::seq_cst}: a load operation performs an acquire operation on the affected memory location. @@ -2678,50 +2978,21 @@ and atomic loads should observe atomic stores, within a reasonable amount of time. -\indexlibraryglobal{kill_dependency}% -\begin{itemdecl} -template - T kill_dependency(T y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The argument does not carry a dependency to the return -value\iref{intro.multithread}. - -\pnum -\returns -\tcode{y}. -\end{itemdescr} - - \rSec2[atomics.lockfree]{Lock-free property} -\indexlibraryglobal{ATOMIC_BOOL_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_CHAR_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_CHAR8_T_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_CHAR16_T_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_CHAR32_T_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_WCHAR_T_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_SHORT_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_INT_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_LONG_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_LLONG_LOCK_FREE}% -\indexlibraryglobal{ATOMIC_POINTER_LOCK_FREE}% \indeximpldef{values of various \tcode{ATOMIC_..._LOCK_FREE} macros} \begin{codeblock} -#define ATOMIC_BOOL_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR8_T_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR16_T_LOCK_FREE @\unspec@ -#define ATOMIC_CHAR32_T_LOCK_FREE @\unspec@ -#define ATOMIC_WCHAR_T_LOCK_FREE @\unspec@ -#define ATOMIC_SHORT_LOCK_FREE @\unspec@ -#define ATOMIC_INT_LOCK_FREE @\unspec@ -#define ATOMIC_LONG_LOCK_FREE @\unspec@ -#define ATOMIC_LLONG_LOCK_FREE @\unspec@ -#define ATOMIC_POINTER_LOCK_FREE @\unspec@ +#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_CHAR8_T_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\unspec@ +#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\unspec@ \end{codeblock} \pnum @@ -2829,34 +3100,36 @@ T* ptr; // \expos public: - using value_type = T; + using value_type = remove_cv_t; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; bool is_lock_free() const noexcept; - explicit atomic_ref(T&); - atomic_ref(const atomic_ref&) noexcept; + constexpr explicit atomic_ref(T&); + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; - void store(T, memory_order = memory_order::seq_cst) const noexcept; - T operator=(T) const noexcept; - T load(memory_order = memory_order::seq_cst) const noexcept; - operator T() const noexcept; - - T exchange(T, memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_weak(T&, T, - memory_order, memory_order) const noexcept; - bool compare_exchange_strong(T&, T, - memory_order, memory_order) const noexcept; - bool compare_exchange_weak(T&, T, - memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_strong(T&, T, - memory_order = memory_order::seq_cst) const noexcept; + constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type operator=(value_type) const noexcept; + constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; + constexpr operator value_type() const noexcept; - void wait(T, memory_order = memory_order::seq_cst) const noexcept; - void notify_one() const noexcept; - void notify_all() const noexcept; + constexpr value_type exchange(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() const noexcept; + constexpr void notify_all() const noexcept; + constexpr T* address() const noexcept; }; } \end{codeblock} @@ -2891,6 +3164,11 @@ to enable atomic operations to be applied to the referenced object. \end{note} +\pnum +The program is ill-formed +if \tcode{is_always_lock_free} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{true}. + \rSec3[atomics.ref.ops]{Operations} \indexlibrarymember{required_alignment}{atomic_ref}% @@ -2955,7 +3233,7 @@ \indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}% \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}% \begin{itemdecl} -atomic_ref(T& obj); +constexpr atomic_ref(T& obj); \end{itemdecl} \begin{itemdescr} @@ -2977,7 +3255,7 @@ \indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}% \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}% \begin{itemdecl} -atomic_ref(const atomic_ref& ref) noexcept; +constexpr atomic_ref(const atomic_ref& ref) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2991,10 +3269,15 @@ \indexlibrarymember{store}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{store}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -void store(T desired, memory_order order = memory_order::seq_cst) const noexcept; +constexpr void store(value_type desired, + memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \expects \tcode{order} is @@ -3014,10 +3297,14 @@ \indexlibrarymember{operator=}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{operator=}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -T operator=(T desired) const noexcept; +constexpr value_type operator=(value_type desired) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \effects Equivalent to: @@ -3032,7 +3319,7 @@ \indexlibrarymember{load}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{load}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -T load(memory_order order = memory_order::seq_cst) const noexcept; +constexpr value_type load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3040,8 +3327,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -3058,7 +3344,7 @@ \indexlibrarymember{operator \placeholder{integral-type}}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{operator \placeholder{floating-point-type}}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -operator T() const noexcept; +constexpr operator value_type() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3072,10 +3358,15 @@ \indexlibrarymember{exchange}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{exchange}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -T exchange(T desired, memory_order order = memory_order::seq_cst) const noexcept; +constexpr value_type exchange(value_type desired, + memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \effects Atomically replaces the value referenced by \tcode{*ptr} @@ -3098,27 +3389,30 @@ \indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -bool compare_exchange_weak(T& expected, T desired, +constexpr bool compare_exchange_weak(value_type& expected, value_type desired, memory_order success, memory_order failure) const noexcept; -bool compare_exchange_strong(T& expected, T desired, +constexpr bool compare_exchange_strong(value_type& expected, value_type desired, memory_order success, memory_order failure) const noexcept; -bool compare_exchange_weak(T& expected, T desired, +constexpr bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order::seq_cst) const noexcept; -bool compare_exchange_strong(T& expected, T desired, +constexpr bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \expects \tcode{failure} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac\-quire}, or -\tcode{memory_order::seq_cst}. +\tcode{memory_order::acquire}, or +\tcode{memory_order::\linebreak seq_cst}. \pnum \effects @@ -3175,7 +3469,7 @@ \indexlibrarymember{wait}{atomic_ref}% \begin{itemdecl} -void wait(T old, memory_order order = memory_order::seq_cst) const noexcept; +constexpr void wait(value_type old, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3183,8 +3477,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac- \linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -3209,10 +3502,14 @@ \indexlibrarymember{notify_one}{atomic_ref}% \begin{itemdecl} -void notify_one() const noexcept; +constexpr void notify_one() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \effects Unblocks the execution of at least one atomic waiting operation on \tcode{*ptr} @@ -3227,10 +3524,14 @@ \indexlibrarymember{notify_all}{atomic_ref}% \begin{itemdecl} -void notify_all() const noexcept; +constexpr void notify_all() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v} is \tcode{false}. + \pnum \effects Unblocks the execution of all atomic waiting operations on \tcode{*ptr} @@ -3238,8 +3539,19 @@ \pnum \remarks - This function is an atomic notifying operation\iref{atomics.wait} - on atomic object \tcode{*ptr}. +This function is an atomic notifying operation\iref{atomics.wait} +on atomic object \tcode{*ptr}. +\end{itemdescr} + +\indexlibrarymember{address}{atomic_ref}% +\begin{itemdecl} +constexpr T* address() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{ptr}. \end{itemdescr} \rSec3[atomics.ref.int]{Specializations for integral types} @@ -3247,23 +3559,7 @@ \pnum \indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}}% There are specializations of the \tcode{atomic_ref} class template -for the integral types -\tcode{char}, -\tcode{signed char}, -\tcode{unsigned char}, -\tcode{short}, -\tcode{unsigned short}, -\tcode{int}, -\tcode{unsigned int}, -\tcode{long}, -\tcode{unsigned long}, -\tcode{long long}, -\tcode{unsigned long long}, -\keyword{char8_t}, -\keyword{char16_t}, -\keyword{char32_t}, -\keyword{wchar_t}, -and any other types needed by the typedefs in the header \libheaderref{cstdint}. +for all integral types except \cv{} \tcode{bool}. For each such type \tcode{\placeholder{integral-type}}, the specialization \tcode{atomic_ref<\placeholder{integral-type}>} provides additional atomic operations appropriate to integral types. @@ -3272,6 +3568,11 @@ uses the primary template\iref{atomics.ref.generic}. \end{note} +\pnum +The program is ill-formed +if \tcode{is_always_lock_free} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{true}. + \begin{codeblock} namespace std { template<> struct atomic_ref<@\placeholder{integral-type}@> { @@ -3279,61 +3580,62 @@ @\placeholder{integral-type}@* ptr; // \expos public: - using value_type = @\placeholder{integral-type}@; + using value_type = remove_cv_t<@\placeholder{integral-type}@>; using difference_type = value_type; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; bool is_lock_free() const noexcept; - explicit atomic_ref(@\placeholder{integral-type}@&); - atomic_ref(const atomic_ref&) noexcept; + constexpr explicit atomic_ref(@\placeholder{integral-type}@&); + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; - void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ operator=(@\placeholder{integral-type}@) const noexcept; - @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const noexcept; - operator @\placeholdernc{integral-type}@() const noexcept; - - @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholder{integral-type}@, - memory_order, memory_order) const noexcept; - bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholder{integral-type}@, - memory_order, memory_order) const noexcept; - bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholder{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholder{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; + constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type operator=(value_type) const noexcept; + constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; + constexpr operator value_type() const noexcept; - @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_max(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - @\placeholdernc{integral-type}@ fetch_min(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) const noexcept; - - @\placeholdernc{integral-type}@ operator++(int) const noexcept; - @\placeholdernc{integral-type}@ operator--(int) const noexcept; - @\placeholdernc{integral-type}@ operator++() const noexcept; - @\placeholdernc{integral-type}@ operator--() const noexcept; - @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) const noexcept; - @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) const noexcept; - @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) const noexcept; - @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) const noexcept; - @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) const noexcept; - - void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const noexcept; - void notify_one() const noexcept; - void notify_all() const noexcept; + constexpr value_type exchange(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr value_type fetch_add(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_sub(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_and(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_or(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_xor(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_max(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_min(value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr value_type operator++(int) const noexcept; + constexpr value_type operator--(int) const noexcept; + constexpr value_type operator++() const noexcept; + constexpr value_type operator--() const noexcept; + constexpr value_type operator+=(value_type) const noexcept; + constexpr value_type operator-=(value_type) const noexcept; + constexpr value_type operator&=(value_type) const noexcept; + constexpr value_type operator|=(value_type) const noexcept; + constexpr value_type operator^=(value_type) const noexcept; + + constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() const noexcept; + constexpr void notify_all() const noexcept; + constexpr @\placeholder{integral-type}@* address() const noexcept; }; } \end{codeblock} @@ -3355,11 +3657,15 @@ \indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{fetch_xor}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -@\placeholdernc{integral-type}@ fetch_@\placeholdernc{key}@(@\placeholdernc{integral-type}@ operand, +constexpr value_type fetch_@\placeholdernc{key}@(value_type operand, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}. + \pnum \effects Atomically replaces the value referenced by \tcode{*ptr} with @@ -3398,10 +3704,14 @@ \indexlibrarymember{operator"|=}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{operator\caret=}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -@\placeholdernc{integral-type}@ operator @\placeholder{op}@=(@\placeholdernc{integral-type}@ operand) const noexcept; +constexpr value_type operator @\placeholder{op}@=(value_type operand) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}. + \pnum \effects Equivalent to: @@ -3413,11 +3723,16 @@ \pnum \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}}% There are specializations of the \tcode{atomic_ref} class template -for all cv-unqualified floating-point types. +for all floating-point types. For each such type \tcode{\placeholder{floating-point-type}}, the specialization \tcode{atomic_ref<\placeholder{floating-\-point}>} provides additional atomic operations appropriate to floating-point types. +\pnum +The program is ill-formed +if \tcode{is_always_lock_free} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{true}. + \begin{codeblock} namespace std { template<> struct atomic_ref<@\placeholder{floating-point-type}@> { @@ -3425,44 +3740,47 @@ @\placeholder{floating-point-type}@* ptr; // \expos public: - using value_type = @\placeholder{floating-point-type}@; + using value_type = remove_cv_t<@\placeholder{floating-point-type}@>; using difference_type = value_type; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; bool is_lock_free() const noexcept; - explicit atomic_ref(@\placeholder{floating-point-type}@&); - atomic_ref(const atomic_ref&) noexcept; + constexpr explicit atomic_ref(@\placeholder{floating-point-type}@&); + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; - void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - @\placeholder{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) const noexcept; - @\placeholder{floating-point-type}@ load(memory_order = memory_order::seq_cst) const noexcept; - operator @\placeholdernc{floating-point-type}@() const noexcept; + constexpr void store(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type operator=(value_type) const noexcept; + constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; + constexpr operator @\placeholdernc{floating-point-type}@() const noexcept; - @\placeholder{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, + constexpr value_type exchange(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_weak(value_type&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) const noexcept; - bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_strong(value_type&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) const noexcept; - bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_weak(value_type&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_strong(value_type&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - @\placeholder{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@, + constexpr value_type fetch_add(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - @\placeholder{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@, + constexpr value_type fetch_sub(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - @\placeholder{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) const noexcept; - @\placeholder{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) const noexcept; + constexpr value_type operator+=(value_type) const noexcept; + constexpr value_type operator-=(value_type) const noexcept; - void wait(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; - void notify_one() const noexcept; - void notify_all() const noexcept; + constexpr void wait(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() const noexcept; + constexpr void notify_all() const noexcept; + constexpr @\placeholder{floating-point-type}@* address() const noexcept; }; } \end{codeblock} @@ -3479,11 +3797,15 @@ \indexlibrarymember{fetch_add}{atomic_ref<\placeholder{floating-point-type}>}% \indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -@\placeholder{floating-point-type}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point-type}@ operand, +constexpr value_type fetch_@\placeholdernc{key}@(value_type operand, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\exposid{floating-point-type}>} is \tcode{false}. + \pnum \effects Atomically replaces the value referenced by \tcode{*ptr} with @@ -3503,20 +3825,24 @@ the result is unspecified, but the operations otherwise have no undefined behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}} should conform to -the \tcode{std::numeric_limits<\placeholder{floating-point-type}>} traits +the \tcode{std::numeric_limits} traits associated with the floating-point type\iref{limits.syn}. The floating-point environment\iref{cfenv} -for atomic arithmetic operations on \tcode{\placeholder{floating-point-type}} +for atomic arithmetic operations on \tcode{\placeholder{floating-\newline point-type}} may be different than the calling thread's floating-point environment. \end{itemdescr} \indexlibrarymember{operator+=}{atomic_ref<\placeholder{floating-point-type}>}% \indexlibrarymember{operator-=}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} -@\placeholder{floating-point-type}@ operator @\placeholder{op}@=(@\placeholder{floating-point-type}@ operand) const noexcept; +constexpr value_type operator @\placeholder{op}@=(value_type operand) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\exposid{floating-point-type}>} is \tcode{false}. + \pnum \effects Equivalent to: @@ -3526,54 +3852,72 @@ \rSec3[atomics.ref.pointer]{Partial specialization for pointers} \indexlibraryglobal{atomic_ref}% +\pnum +There are specializations of the \tcode{atomic_ref} class template +for all pointer-to-object types. +For each such type \placeholder{pointer-type}, +the specialization \tcode{atomic_ref<\placeholder{pointer-type}>} provides +additional atomic operations appropriate to pointer types. + +\pnum +The program is ill-formed +if \tcode{is_always_lock_free} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{true}. + \begin{codeblock} namespace std { - template struct atomic_ref { + template struct atomic_ref<@\placeholder{pointer-type}@> { private: - T** ptr; // \expos + @\placeholder{pointer-type}@* ptr; // \expos public: - using value_type = T*; + using value_type = remove_cv_t<@\placeholder{pointer-type}@>; using difference_type = ptrdiff_t; static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; bool is_lock_free() const noexcept; - explicit atomic_ref(T*&); - atomic_ref(const atomic_ref&) noexcept; + constexpr explicit atomic_ref(@\placeholder{pointer-type}@&); + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; - void store(T*, memory_order = memory_order::seq_cst) const noexcept; - T* operator=(T*) const noexcept; - T* load(memory_order = memory_order::seq_cst) const noexcept; - operator T*() const noexcept; - - T* exchange(T*, memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_weak(T*&, T*, - memory_order, memory_order) const noexcept; - bool compare_exchange_strong(T*&, T*, - memory_order, memory_order) const noexcept; - bool compare_exchange_weak(T*&, T*, - memory_order = memory_order::seq_cst) const noexcept; - bool compare_exchange_strong(T*&, T*, - memory_order = memory_order::seq_cst) const noexcept; + constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type operator=(value_type) const noexcept; + constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; + constexpr operator value_type() const noexcept; - T* fetch_add(difference_type, memory_order = memory_order::seq_cst) const noexcept; - T* fetch_sub(difference_type, memory_order = memory_order::seq_cst) const noexcept; - T* fetch_max(T*, memory_order = memory_order::seq_cst) const noexcept; - T* fetch_min(T*, memory_order = memory_order::seq_cst) const noexcept; - - T* operator++(int) const noexcept; - T* operator--(int) const noexcept; - T* operator++() const noexcept; - T* operator--() const noexcept; - T* operator+=(difference_type) const noexcept; - T* operator-=(difference_type) const noexcept; - - void wait(T*, memory_order = memory_order::seq_cst) const noexcept; - void notify_one() const noexcept; - void notify_all() const noexcept; + constexpr value_type exchange(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order, memory_order) const noexcept; + constexpr bool compare_exchange_weak(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr bool compare_exchange_strong(value_type&, value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr value_type fetch_add(difference_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_sub(difference_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_max(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_min(value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr value_type operator++(int) const noexcept; + constexpr value_type operator--(int) const noexcept; + constexpr value_type operator++() const noexcept; + constexpr value_type operator--() const noexcept; + constexpr value_type operator+=(difference_type) const noexcept; + constexpr value_type operator-=(difference_type) const noexcept; + + constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() const noexcept; + constexpr void notify_all() const noexcept; + constexpr @\placeholder{pointer-type}@* address() const noexcept; }; } \end{codeblock} @@ -3592,13 +3936,18 @@ \indexlibrarymember{fetch_max}{atomic_ref}% \indexlibrarymember{fetch_min}{atomic_ref}% \begin{itemdecl} -T* fetch_@\placeholdernc{key}@(difference_type operand, memory_order order = memory_order::seq_cst) const noexcept; +constexpr value_type fetch_@\placeholdernc{key}@(difference_type operand, + memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}. + \pnum \mandates -\tcode{T} is a complete object type. +\tcode{remove_pointer_t<\placeholder{pointer-type}>} is a complete object type. \pnum \effects @@ -3631,15 +3980,17 @@ \end{note} \end{itemdescr} - - \indexlibrarymember{operator+=}{atomic_ref}% \indexlibrarymember{operator-=}{atomic_ref}% \begin{itemdecl} -T* operator @\placeholder{op}@=(difference_type operand) const noexcept; +constexpr value_type operator @\placeholder{op}@=(difference_type operand) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}. + \pnum \effects Equivalent to: @@ -3649,13 +4000,25 @@ \rSec3[atomics.ref.memop]{Member operators common to integers and pointers to objects} +\pnum +Let \placeholder{referred-type} +be \placeholder{pointer-type} +for the specializations in \ref{atomics.ref.pointer} and +be \placeholder{integral-type} +for the specializations in \ref{atomics.ref.int}. + + \indexlibrarymember{operator++}{atomic_ref}% \indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -value_type operator++(int) const noexcept; +constexpr value_type operator++(int) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return fetch_add(1);} @@ -3664,10 +4027,14 @@ \indexlibrarymember{operator--}{atomic_ref}% \indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -value_type operator--(int) const noexcept; +constexpr value_type operator--(int) const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return fetch_sub(1);} @@ -3676,10 +4043,14 @@ \indexlibrarymember{operator++}{atomic_ref}% \indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -value_type operator++() const noexcept; +constexpr value_type operator++() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return fetch_add(1) + 1;} @@ -3688,10 +4059,14 @@ \indexlibrarymember{operator--}{atomic_ref}% \indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} -value_type operator--() const noexcept; +constexpr value_type operator--() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return fetch_sub(1) - 1;} @@ -3720,31 +4095,31 @@ atomic& operator=(const atomic&) volatile = delete; T load(memory_order = memory_order::seq_cst) const volatile noexcept; - T load(memory_order = memory_order::seq_cst) const noexcept; + constexpr T load(memory_order = memory_order::seq_cst) const noexcept; operator T() const volatile noexcept; - operator T() const noexcept; + constexpr operator T() const noexcept; void store(T, memory_order = memory_order::seq_cst) volatile noexcept; - void store(T, memory_order = memory_order::seq_cst) noexcept; + constexpr void store(T, memory_order = memory_order::seq_cst) noexcept; T operator=(T) volatile noexcept; - T operator=(T) noexcept; + constexpr T operator=(T) noexcept; T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept; - T exchange(T, memory_order = memory_order::seq_cst) noexcept; + constexpr T exchange(T, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept; + constexpr bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept; bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept; + constexpr bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept; bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept; void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept; - void wait(T, memory_order = memory_order::seq_cst) const noexcept; + constexpr void wait(T, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; - void notify_one() noexcept; + constexpr void notify_one() noexcept; void notify_all() volatile noexcept; - void notify_all() noexcept; + constexpr void notify_all() noexcept; }; } \end{codeblock} @@ -3758,8 +4133,9 @@ \item \tcode{is_trivially_copyable_v}, \item \tcode{is_copy_constructible_v}, \item \tcode{is_move_constructible_v}, -\item \tcode{is_copy_assignable_v}, or -\item \tcode{is_move_assignable_v} +\item \tcode{is_copy_assignable_v}, +\item \tcode{is_move_assignable_v}, or +\item \tcode{same_as>}, \end{itemize} is \tcode{false}. \begin{note} @@ -3790,7 +4166,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{is_default_constructible_v} is \tcode{true}. \pnum @@ -3872,7 +4248,7 @@ \indexlibrarymember{store}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; -void store(T desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr void store(T desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3901,7 +4277,7 @@ \indexlibrarymember{operator=}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} T operator=(T desired) volatile noexcept; -T operator=(T desired) noexcept; +constexpr T operator=(T desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3927,7 +4303,7 @@ \indexlibrarymember{load}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} T load(memory_order order = memory_order::seq_cst) const volatile noexcept; -T load(memory_order order = memory_order::seq_cst) const noexcept; +constexpr T load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3940,8 +4316,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -3959,7 +4334,7 @@ \indexlibrarymember{operator \placeholder{floating-point-type}}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} operator T() const volatile noexcept; -operator T() const noexcept; +constexpr operator T() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3982,7 +4357,7 @@ \indexlibrarymember{exchange}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; -T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4018,19 +4393,19 @@ \begin{itemdecl} bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; -bool compare_exchange_weak(T& expected, T desired, +constexpr bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; -bool compare_exchange_strong(T& expected, T desired, +constexpr bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) noexcept; bool compare_exchange_weak(T& expected, T desired, memory_order order = memory_order::seq_cst) volatile noexcept; -bool compare_exchange_weak(T& expected, T desired, +constexpr bool compare_exchange_weak(T& expected, T desired, memory_order order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order order = memory_order::seq_cst) volatile noexcept; -bool compare_exchange_strong(T& expected, T desired, +constexpr bool compare_exchange_strong(T& expected, T desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} @@ -4044,9 +4419,8 @@ \expects \tcode{failure} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac\-quire}, or -\tcode{memory_order::seq_cst}. +\tcode{memory_order::acquire}, or +\tcode{memory_order::\linebreak seq_cst}. \pnum \effects @@ -4140,7 +4514,7 @@ operations apply, the comparisons can fail for values that compare equal with \tcode{operator==} if the value representation has trap bits or alternate representations of the same value. Notably, on implementations conforming to -ISO/IEC/IEEE 60559, floating-point \tcode{-0.0} and \tcode{+0.0} +\IsoFloatUndated{}, floating-point \tcode{-0.0} and \tcode{+0.0} will not compare equal with \tcode{memcmp} but will compare equal with \tcode{operator==}, and NaNs with the same payload will compare equal with \tcode{memcmp} but will not compare equal with \tcode{operator==}. @@ -4191,7 +4565,7 @@ \indexlibrarymember{wait}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} void wait(T old, memory_order order = memory_order::seq_cst) const volatile noexcept; -void wait(T old, memory_order order = memory_order::seq_cst) const noexcept; +constexpr void wait(T old, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4199,8 +4573,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -4228,7 +4601,7 @@ \indexlibrarymember{notify_one}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} void notify_one() volatile noexcept; -void notify_one() noexcept; +constexpr void notify_one() noexcept; \end{itemdecl} \begin{itemdescr} @@ -4249,7 +4622,7 @@ \indexlibrarymember{notify_all}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} void notify_all() volatile noexcept; -void notify_all() noexcept; +constexpr void notify_all() noexcept; \end{itemdecl} \begin{itemdescr} @@ -4309,89 +4682,89 @@ atomic& operator=(const atomic&) volatile = delete; void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; + constexpr void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ operator=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator=(@\placeholdernc{integral-type}@) noexcept; @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const volatile noexcept; - @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const noexcept; + constexpr @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const noexcept; operator @\placeholdernc{integral-type}@() const volatile noexcept; - operator @\placeholdernc{integral-type}@() const noexcept; + constexpr operator @\placeholdernc{integral-type}@() const noexcept; @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, + constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) noexcept; bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, + constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) noexcept; bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, + constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, + constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ operator++(int) volatile noexcept; - @\placeholdernc{integral-type}@ operator++(int) noexcept; + constexpr @\placeholdernc{integral-type}@ operator++(int) noexcept; @\placeholdernc{integral-type}@ operator--(int) volatile noexcept; - @\placeholdernc{integral-type}@ operator--(int) noexcept; + constexpr @\placeholdernc{integral-type}@ operator--(int) noexcept; @\placeholdernc{integral-type}@ operator++() volatile noexcept; - @\placeholdernc{integral-type}@ operator++() noexcept; + constexpr @\placeholdernc{integral-type}@ operator++() noexcept; @\placeholdernc{integral-type}@ operator--() volatile noexcept; - @\placeholdernc{integral-type}@ operator--() noexcept; + constexpr @\placeholdernc{integral-type}@ operator--() noexcept; @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) noexcept; @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) noexcept; @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) noexcept; @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) noexcept; @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) volatile noexcept; - @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) noexcept; + constexpr @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) noexcept; void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const volatile noexcept; - void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const noexcept; + constexpr void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; - void notify_one() noexcept; + constexpr void notify_one() noexcept; void notify_all() volatile noexcept; - void notify_all() noexcept; + constexpr void notify_all() noexcept; }; } \end{codeblock} @@ -4465,7 +4838,7 @@ \indexlibrarymember{fetch_xor}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; +constexpr T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4514,7 +4887,7 @@ \indexlibrarymember{operator\caret=}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} T operator @\placeholder{op}@=(T operand) volatile noexcept; -T operator @\placeholder{op}@=(T operand) noexcept; +constexpr T operator @\placeholder{op}@=(T operand) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4555,55 +4928,56 @@ atomic& operator=(const atomic&) volatile = delete; void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; + constexpr void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) volatile noexcept; - @\placeholdernc{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) noexcept; + constexpr @\placeholdernc{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) noexcept; @\placeholdernc{floating-point-type}@ load(memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{floating-point-type}@ load(memory_order = memory_order::seq_cst) noexcept; + constexpr @\placeholdernc{floating-point-type}@ load(memory_order = memory_order::seq_cst) noexcept; operator @\placeholdernc{floating-point-type}@() volatile noexcept; - operator @\placeholdernc{floating-point-type}@() noexcept; + constexpr operator @\placeholdernc{floating-point-type}@() noexcept; @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, + constexpr @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) noexcept; bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) noexcept; bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, + constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@, + constexpr @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@, + constexpr @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) volatile noexcept; - @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) noexcept; + constexpr @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) noexcept; @\placeholdernc{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) volatile noexcept; - @\placeholdernc{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) noexcept; + constexpr @\placeholdernc{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) noexcept; void wait(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const volatile noexcept; - void wait(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const noexcept; + constexpr void wait(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; - void notify_one() noexcept; + constexpr void notify_one() noexcept; void notify_all() volatile noexcept; - void notify_all() noexcept; + constexpr void notify_all() noexcept; }; } \end{codeblock} @@ -4630,7 +5004,7 @@ \indexlibrarymember{fetch_sub}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; +constexpr T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4669,7 +5043,7 @@ \indexlibrarymember{operator-=}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} T operator @\placeholder{op}@=(T operand) volatile noexcept; -T operator @\placeholder{op}@=(T operand) noexcept; +constexpr T operator @\placeholder{op}@=(T operand) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4714,57 +5088,57 @@ atomic& operator=(const atomic&) volatile = delete; void store(T*, memory_order = memory_order::seq_cst) volatile noexcept; - void store(T*, memory_order = memory_order::seq_cst) noexcept; + constexpr void store(T*, memory_order = memory_order::seq_cst) noexcept; T* operator=(T*) volatile noexcept; - T* operator=(T*) noexcept; + constexpr T* operator=(T*) noexcept; T* load(memory_order = memory_order::seq_cst) const volatile noexcept; - T* load(memory_order = memory_order::seq_cst) const noexcept; + constexpr T* load(memory_order = memory_order::seq_cst) const noexcept; operator T*() const volatile noexcept; - operator T*() const noexcept; + constexpr operator T*() const noexcept; T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept; - T* exchange(T*, memory_order = memory_order::seq_cst) noexcept; + constexpr T* exchange(T*, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; + constexpr bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; + constexpr bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; bool compare_exchange_weak(T*&, T*, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_weak(T*&, T*, + constexpr bool compare_exchange_weak(T*&, T*, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T*&, T*, memory_order = memory_order::seq_cst) volatile noexcept; - bool compare_exchange_strong(T*&, T*, + constexpr bool compare_exchange_strong(T*&, T*, memory_order = memory_order::seq_cst) noexcept; T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; + constexpr T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; + constexpr T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; T* fetch_max(T*, memory_order = memory_order::seq_cst) volatile noexcept; - T* fetch_max(T*, memory_order = memory_order::seq_cst) noexcept; + constexpr T* fetch_max(T*, memory_order = memory_order::seq_cst) noexcept; T* fetch_min(T*, memory_order = memory_order::seq_cst) volatile noexcept; - T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept; + constexpr T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept; T* operator++(int) volatile noexcept; - T* operator++(int) noexcept; + constexpr T* operator++(int) noexcept; T* operator--(int) volatile noexcept; - T* operator--(int) noexcept; + constexpr T* operator--(int) noexcept; T* operator++() volatile noexcept; - T* operator++() noexcept; + constexpr T* operator++() noexcept; T* operator--() volatile noexcept; - T* operator--() noexcept; + constexpr T* operator--() noexcept; T* operator+=(ptrdiff_t) volatile noexcept; - T* operator+=(ptrdiff_t) noexcept; + constexpr T* operator+=(ptrdiff_t) noexcept; T* operator-=(ptrdiff_t) volatile noexcept; - T* operator-=(ptrdiff_t) noexcept; + constexpr T* operator-=(ptrdiff_t) noexcept; void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; - void wait(T*, memory_order = memory_order::seq_cst) const noexcept; + constexpr void wait(T*, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; - void notify_one() noexcept; + constexpr void notify_one() noexcept; void notify_all() volatile noexcept; - void notify_all() noexcept; + constexpr void notify_all() noexcept; }; } \end{codeblock} @@ -4820,7 +5194,7 @@ \indexlibrarymember{fetch_sub}{atomic}% \begin{itemdecl} T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept; -T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept; +constexpr T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4870,7 +5244,7 @@ \indexlibrarymember{operator-=}{atomic}% \begin{itemdecl} T* operator @\placeholder{op}@=(ptrdiff_t operand) volatile noexcept; -T* operator @\placeholder{op}@=(ptrdiff_t operand) noexcept; +constexpr T* operator @\placeholder{op}@=(ptrdiff_t operand) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4890,7 +5264,7 @@ \indexlibrarymember{operator++}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} value_type operator++(int) volatile noexcept; -value_type operator++(int) noexcept; +constexpr value_type operator++(int) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4908,7 +5282,7 @@ \indexlibrarymember{operator--}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} value_type operator--(int) volatile noexcept; -value_type operator--(int) noexcept; +constexpr value_type operator--(int) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4926,7 +5300,7 @@ \indexlibrarymember{operator++}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} value_type operator++() volatile noexcept; -value_type operator++() noexcept; +constexpr value_type operator++() noexcept; \end{itemdecl} \begin{itemdescr} @@ -4944,7 +5318,7 @@ \indexlibrarymember{operator--}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} value_type operator--() volatile noexcept; -value_type operator--() noexcept; +constexpr value_type operator--() noexcept; \end{itemdecl} \begin{itemdescr} @@ -5072,7 +5446,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{p\{\}}. +Value-initializes \tcode{p}. \end{itemdescr} \indexlibraryctor{atomic>}% @@ -5149,8 +5523,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5205,9 +5578,8 @@ \expects \tcode{failure} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac\-quire}, or -\tcode{memory_order::seq_cst}. +\tcode{memory_order::acquire}, or +\tcode{memory_order::\linebreak seq_cst}. \pnum \effects @@ -5293,8 +5665,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5400,7 +5771,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{p\{\}}. +Value-initializes \tcode{p}. \end{itemdescr} \indexlibraryctor{atomic>}% @@ -5466,8 +5837,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5521,9 +5891,8 @@ \expects \tcode{failure} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac\-quire}, or -\tcode{memory_order::seq_cst}. +\tcode{memory_order::acquire}, or +\tcode{memory_order::\linebreak seq_cst}. \pnum \effects @@ -5609,8 +5978,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5697,18 +6065,18 @@ atomic_flag& operator=(const atomic_flag&) volatile = delete; bool test(memory_order = memory_order::seq_cst) const volatile noexcept; - bool test(memory_order = memory_order::seq_cst) const noexcept; + constexpr bool test(memory_order = memory_order::seq_cst) const noexcept; bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept; - bool test_and_set(memory_order = memory_order::seq_cst) noexcept; + constexpr bool test_and_set(memory_order = memory_order::seq_cst) noexcept; void clear(memory_order = memory_order::seq_cst) volatile noexcept; - void clear(memory_order = memory_order::seq_cst) noexcept; + constexpr void clear(memory_order = memory_order::seq_cst) noexcept; void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; - void wait(bool, memory_order = memory_order::seq_cst) const noexcept; + constexpr void wait(bool, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; - void notify_one() noexcept; + constexpr void notify_one() noexcept; void notify_all() volatile noexcept; - void notify_all() noexcept; + constexpr void notify_all() noexcept; }; } \end{codeblock} @@ -5740,13 +6108,13 @@ \indexlibrarymember{test}{atomic_flag}% \begin{itemdecl} bool atomic_flag_test(const volatile atomic_flag* object) noexcept; -bool atomic_flag_test(const atomic_flag* object) noexcept; +constexpr bool atomic_flag_test(const atomic_flag* object) noexcept; bool atomic_flag_test_explicit(const volatile atomic_flag* object, memory_order order) noexcept; -bool atomic_flag_test_explicit(const atomic_flag* object, +constexpr bool atomic_flag_test_explicit(const atomic_flag* object, memory_order order) noexcept; bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept; -bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept; +constexpr bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5757,8 +6125,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5775,11 +6142,11 @@ \indexlibrarymember{test_and_set}{atomic_flag}% \begin{itemdecl} bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept; -bool atomic_flag_test_and_set(atomic_flag* object) noexcept; +constexpr bool atomic_flag_test_and_set(atomic_flag* object) noexcept; bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept; -bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept; +constexpr bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept; bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept; -bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept; +constexpr bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5798,11 +6165,11 @@ \indexlibrarymember{clear}{atomic_flag}% \begin{itemdecl} void atomic_flag_clear(volatile atomic_flag* object) noexcept; -void atomic_flag_clear(atomic_flag* object) noexcept; +constexpr void atomic_flag_clear(atomic_flag* object) noexcept; void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept; -void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept; +constexpr void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept; void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept; -void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept; +constexpr void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5824,14 +6191,14 @@ \indexlibrarymember{wait}{atomic_flag}% \begin{itemdecl} void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept; -void atomic_flag_wait(const atomic_flag* object, bool old) noexcept; +constexpr void atomic_flag_wait(const atomic_flag* object, bool old) noexcept; void atomic_flag_wait_explicit(const volatile atomic_flag* object, bool old, memory_order order) noexcept; -void atomic_flag_wait_explicit(const atomic_flag* object, +constexpr void atomic_flag_wait_explicit(const atomic_flag* object, bool old, memory_order order) noexcept; void atomic_flag::wait(bool old, memory_order order = memory_order::seq_cst) const volatile noexcept; -void atomic_flag::wait(bool old, memory_order order = +constexpr void atomic_flag::wait(bool old, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} @@ -5846,8 +6213,7 @@ \expects \tcode{order} is \tcode{memory_order::relaxed}, -\tcode{memory_order::consume}, -\tcode{memory_order::ac-\linebreak quire}, or +\tcode{memory_order::acquire}, or \tcode{memory_order::seq_cst}. \pnum @@ -5870,9 +6236,9 @@ \begin{itemdecl} void atomic_flag_notify_one(volatile atomic_flag* object) noexcept; -void atomic_flag_notify_one(atomic_flag* object) noexcept; +constexpr void atomic_flag_notify_one(atomic_flag* object) noexcept; void atomic_flag::notify_one() volatile noexcept; -void atomic_flag::notify_one() noexcept; +constexpr void atomic_flag::notify_one() noexcept; \end{itemdecl} \begin{itemdescr} @@ -5889,9 +6255,9 @@ \begin{itemdecl} void atomic_flag_notify_all(volatile atomic_flag* object) noexcept; -void atomic_flag_notify_all(atomic_flag* object) noexcept; +constexpr void atomic_flag_notify_all(atomic_flag* object) noexcept; void atomic_flag::notify_all() volatile noexcept; -void atomic_flag::notify_all() noexcept; +constexpr void atomic_flag::notify_all() noexcept; \end{itemdecl} \begin{itemdescr} @@ -5905,9 +6271,8 @@ This function is an atomic notifying operation\iref{atomics.wait}. \end{itemdescr} -\indexlibraryglobal{ATOMIC_FLAG_INIT}% \begin{itemdecl} -#define ATOMIC_FLAG_INIT @\seebelow@ +#define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelow@ \end{itemdecl} \begin{itemdescr} @@ -5958,7 +6323,7 @@ \indexlibraryglobal{atomic_thread_fence}% \begin{itemdecl} -extern "C" void atomic_thread_fence(memory_order order) noexcept; +extern "C" constexpr void atomic_thread_fence(memory_order order) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5968,7 +6333,7 @@ \begin{itemize} \item has no effects, if \tcode{order == memory_order::relaxed}; -\item is an acquire fence, if \tcode{order == memory_order::acquire} or \tcode{order == memory_order::consume}; +\item is an acquire fence, if \tcode{order == memory_order::acquire}; \item is a release fence, if \tcode{order == memory_order::release}; @@ -5980,7 +6345,7 @@ \indexlibraryglobal{atomic_signal_fence}% \begin{itemdecl} -extern "C" void atomic_signal_fence(memory_order order) noexcept; +extern "C" constexpr void atomic_signal_fence(memory_order order) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6008,18 +6373,18 @@ template using @\exposid{std-atomic}@ = std::atomic; // \expos -#define _Atomic(T) @\exposid{std-atomic}@ +#define @\libmacro{_Atomic}@(T) @\exposid{std-atomic}@ -#define ATOMIC_BOOL_LOCK_FREE @\seebelow@ -#define ATOMIC_CHAR_LOCK_FREE @\seebelow@ -#define ATOMIC_CHAR16_T_LOCK_FREE @\seebelow@ -#define ATOMIC_CHAR32_T_LOCK_FREE @\seebelow@ -#define ATOMIC_WCHAR_T_LOCK_FREE @\seebelow@ -#define ATOMIC_SHORT_LOCK_FREE @\seebelow@ -#define ATOMIC_INT_LOCK_FREE @\seebelow@ -#define ATOMIC_LONG_LOCK_FREE @\seebelow@ -#define ATOMIC_LLONG_LOCK_FREE @\seebelow@ -#define ATOMIC_POINTER_LOCK_FREE @\seebelow@ +#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\seebelow@ +#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\seebelow@ using std::@\libglobal{memory_order}@; // \seebelow using std::@\libglobal{memory_order_relaxed}@; // \seebelow @@ -6103,7 +6468,7 @@ using std::@\libglobal{atomic_flag_test_and_set_explicit}@; // \seebelow using std::@\libglobal{atomic_flag_clear}@; // \seebelow using std::@\libglobal{atomic_flag_clear_explicit}@; // \seebelow -#define ATOMIC_FLAG_INIT @\seebelow@ +#define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelow@ using std::@\libglobal{atomic_thread_fence}@; // \seebelow using std::@\libglobal{atomic_signal_fence}@; // \seebelow @@ -6113,7 +6478,7 @@ Each \grammarterm{using-declaration} for some name $A$ in the synopsis above makes available the same entity as \tcode{std::$A$} declared in \libheaderrefx{atomic}{atomics.syn}. -Each macro listed above other than \tcode{_Atomic(T)} +Each macro listed above other than \tcode{\libmacro{_Atomic}(T)} is defined as in \libheader{atomic}. It is unspecified whether \libheader{stdatomic.h} makes available any declarations in namespace \tcode{std}. @@ -6158,7 +6523,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; @@ -6208,7 +6573,7 @@ \rSec2[thread.mutex.requirements]{Mutex requirements} -\rSec3[thread.mutex.requirements.general]{In general} +\rSec3[thread.mutex.requirements.general]{General} \pnum A mutex object facilitates protection against data races and allows safe synchronization of @@ -6485,7 +6850,7 @@ released may ownership be acquired by another thread. \pnum -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item it destroys a \tcode{recursive_mutex} object owned by any thread or \item a thread terminates while owning a \tcode{recursive_mutex} object. @@ -6636,7 +7001,7 @@ It is a standard-layout class\iref{class.prop}. \pnum -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item it destroys a \tcode{timed_mutex} object owned by any thread, \item a thread that owns a \tcode{timed_mutex} object calls \tcode{lock()}, @@ -6701,7 +7066,7 @@ may ownership of the object be acquired by another thread. \pnum -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item it destroys a \tcode{recursive_timed_mutex} object owned by any thread, or \item a thread terminates while owning a \tcode{recursive_timed_mutex} object. @@ -6873,7 +7238,7 @@ It is a standard-layout class\iref{class.prop}. \pnum -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item it destroys a \tcode{shared_mutex} object owned by any thread, \item a thread attempts to recursively gain any ownership of a \tcode{shared_mutex}, or @@ -7035,7 +7400,7 @@ It is a standard-layout class\iref{class.prop}. \pnum -The behavior of a program is undefined if: +The behavior of a program is undefined if \begin{itemize} \item it destroys a \tcode{shared_timed_mutex} object owned by any thread, \item a thread attempts to recursively gain any ownership of a \tcode{shared_timed_mutex}, or @@ -7272,7 +7637,7 @@ unique_lock& operator=(const unique_lock&) = delete; unique_lock(unique_lock&& u) noexcept; - unique_lock& operator=(unique_lock&& u); + unique_lock& operator=(unique_lock&& u) noexcept; // \ref{thread.lock.unique.locking}, locking void lock(); @@ -7291,7 +7656,7 @@ // \ref{thread.lock.unique.obs}, observers bool owns_lock() const noexcept; - explicit operator bool () const noexcept; + explicit operator bool() const noexcept; mutex_type* mutex() const noexcept; private: @@ -7459,26 +7824,17 @@ \indexlibrarymember{operator=}{unique_lock}% \begin{itemdecl} -unique_lock& operator=(unique_lock&& u); +unique_lock& operator=(unique_lock&& u) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -If \tcode{owns} calls \tcode{pm->unlock()}. - -\pnum -\ensures -\tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.pm == 0} and \tcode{u.owns == false}. - -\pnum -\begin{note} -With a recursive mutex it is possible for both \tcode{*this} and \tcode{u} to own the same mutex before the assignment. In this case, \tcode{*this} will own the mutex after the assignment and \tcode{u} will not. -\end{note} +Equivalent to: \tcode{unique_lock(std::move(u)).swap(*this)} \pnum -\throws -Nothing. +\returns +\tcode{*this}. \end{itemdescr} \indexlibrarydtor{unique_lock}% @@ -7782,7 +8138,7 @@ // \ref{thread.lock.shared.obs}, observers bool owns_lock() const noexcept; - explicit operator bool () const noexcept; + explicit operator bool() const noexcept; mutex_type* mutex() const noexcept; private: @@ -7965,13 +8321,11 @@ \begin{itemdescr} \pnum \effects -If \tcode{owns} calls \tcode{pm->unlock_shared()}. +Equivalent to: \tcode{shared_lock(std::move(sl)).swap(*this)} \pnum -\ensures -\tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where -\tcode{sl_p} is the state of \tcode{sl} just prior to this assignment), -\tcode{sl.pm == nullptr} and \tcode{sl.owns == false}. +\returns +\tcode{*this}. \end{itemdescr} \rSec4[thread.lock.shared.locking]{Locking} @@ -8429,7 +8783,6 @@ \rSec2[condition.variable.syn]{Header \tcode{} synopsis} \indexheader{condition_variable}% -\indexlibraryglobal{cv_status}% \begin{codeblock} namespace std { // \ref{thread.condition.condvar}, class \tcode{condition_variable} @@ -8440,7 +8793,7 @@ // \ref{thread.condition.nonmember}, non-member functions void notify_all_at_thread_exit(condition_variable& cond, unique_lock lk); - enum class cv_status { no_timeout, timeout }; + enum class @\libglobal{cv_status}@ { @\libmember{no_timeout}{cv_status}@, @\libmember{timeout}{cv_status}@ }; } \end{codeblock} @@ -8465,7 +8818,7 @@ \effects Transfers ownership of the lock associated with \tcode{lk} into internal storage and schedules \tcode{cond} to be notified when the current -thread exits, after all objects of thread storage duration associated with +thread exits, after all objects with thread storage duration associated with the current thread have been destroyed. This notification is equivalent to: \begin{codeblock} lk.unlock(); @@ -8919,7 +9272,7 @@ \rSec3[thread.condition.condvarany.general]{General} \pnum -In this subclause \ref{thread.condition.condvarany}, +In \ref{thread.condition.condvarany}, template arguments for template parameters named \tcode{Lock} shall meet the \oldconcept{Basic\-Lockable} requirements\iref{thread.req.lockable.basic}. @@ -9798,7 +10151,7 @@ barrier(const barrier&) = delete; barrier& operator=(const barrier&) = delete; - [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1); + arrival_token arrive(ptrdiff_t update = 1); void wait(arrival_token&& arrival) const; void arrive_and_wait(); @@ -9919,7 +10272,7 @@ \indexlibrarymember{arrive}{barrier}% \begin{itemdecl} -[[nodiscard]] arrival_token arrive(ptrdiff_t update = 1); +arrival_token arrive(ptrdiff_t update = 1); \end{itemdecl} \begin{itemdescr} @@ -10052,26 +10405,25 @@ \rSec2[future.syn]{Header \tcode{} synopsis} \indexheader{future}% -\indexlibraryglobal{future_errc}% \begin{codeblock} namespace std { - enum class future_errc { - broken_promise = @\impdefx{value of \tcode{future_errc::broken_promise}}@, - future_already_retrieved = @\impdefx{value of \tcode{future_errc::future_already_retrieved}}@, - promise_already_satisfied = @\impdefx{value of \tcode{future_errc::promise_already_satisfied}}@, - no_state = @\impdefx{value of \tcode{future_errc::no_state}}@ + enum class @\libglobal{future_errc}@ { + @\libmember{broken_promise}{future_errc}@ = @\impdefx{value of \tcode{future_errc::broken_promise}}@, + @\libmember{future_already_retrieved}{future_errc}@ = @\impdefx{value of \tcode{future_errc::future_already_retrieved}}@, + @\libmember{promise_already_satisfied}{future_errc}@ = @\impdefx{value of \tcode{future_errc::promise_already_satisfied}}@, + @\libmember{no_state}{future_errc}@ = @\impdefx{value of \tcode{future_errc::no_state}}@ }; - enum class launch : @\unspec{}@ { - async = @\unspec{}@, - deferred = @\unspec{}@, + enum class @\libglobal{launch}@ : @\unspec{}@ { + @\libmember{async}{launch}@ = @\unspec{}@, + @\libmember{deferred}{launch}@ = @\unspec{}@, @\impdefx{last enumerator of \tcode{launch}}@ }; - enum class future_status { - ready, - timeout, - deferred + enum class @\libglobal{future_status}@ { + @\libmember{ready}{future_status}@, + @\libmember{timeout}{future_status}@, + @\libmember{deferred}{future_status}@ }; // \ref{futures.errors}, error handling @@ -10115,10 +10467,10 @@ // \ref{futures.async}, function template \tcode{async} template - [[nodiscard]] future, decay_t...>> + future, decay_t...>> async(F&& f, Args&&... args); template - [[nodiscard]] future, decay_t...>> + future, decay_t...>> async(launch policy, F&& f, Args&&... args); } \end{codeblock} @@ -10259,9 +10611,9 @@ state. The result of a shared state is set by respective functions on the asynchronous provider. -\begin{note} -Such as promises or tasks. -\end{note} +\begin{example} +Promises and tasks are examples of asynchronous providers. +\end{example} The means of setting the result of a shared state is specified in the description of those classes and functions that create such a state object. @@ -10598,7 +10950,7 @@ \effects Stores the value \tcode{r} in the shared state without making that state ready immediately. Schedules that state to be made ready when the current -thread exits, after all objects of thread storage duration associated with the +thread exits, after all objects with thread storage duration associated with the current thread have been destroyed. \pnum @@ -10633,7 +10985,7 @@ \effects Stores the exception pointer \tcode{p} in the shared state without making that state ready immediately. Schedules that state to be made ready when -the current thread exits, after all objects of thread storage duration +the current thread exits, after all objects with thread storage duration associated with the current thread have been destroyed. \pnum @@ -11323,10 +11675,10 @@ \indexlibraryglobal{async}% \begin{itemdecl} template - [[nodiscard]] future, decay_t...>> + future, decay_t...>> async(F&& f, Args&&... args); template - [[nodiscard]] future, decay_t...>> + future, decay_t...>> async(launch policy, F&& f, Args&&... args); \end{itemdecl} @@ -11566,16 +11918,13 @@ \pnum \mandates -\tcode{is_invocable_r_v} is \tcode{true}. - -\pnum -\expects -Invoking a copy of \tcode{f} behaves the same as invoking \tcode{f}. +\tcode{is_invocable_r_v\&, ArgTypes...>} is \tcode{true}. \pnum \effects -Constructs a new \tcode{packaged_task} object with a shared state and -initializes the object's stored task with \tcode{std::forward(f)}. +Constructs a new \tcode{packaged_task} object with +a stored task of type \tcode{decay_t} and a shared state. +Initializes the object's stored task with \tcode{std::forward(f)}. \pnum \throws @@ -11767,7 +12116,7 @@ \tcode{*this}, otherwise the exception thrown by the task is stored. In either case, this is done without making that state ready\iref{futures.state} immediately. Schedules the shared state to be made ready when the current thread exits, -after all objects of thread storage duration associated with the current thread +after all objects with thread storage duration associated with the current thread have been destroyed. \pnum @@ -11897,7 +12246,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; @@ -12232,7 +12581,7 @@ \pnum A hazard-protectable object \tcode{x} is \defn{possibly-reclaimable} -with respect to an evaluation $A$ if: +with respect to an evaluation $A$ if \begin{itemize} \item \tcode{x} is not reclaimed; and @@ -12394,7 +12743,7 @@ hazard_pointer& operator=(hazard_pointer&&) noexcept; ~hazard_pointer(); - [[nodiscard]] bool empty() const noexcept; + bool empty() const noexcept; template T* protect(const atomic& src) noexcept; template bool try_protect(T*& ptr, const atomic& src) noexcept; template void reset_protection(const T* ptr) noexcept; @@ -12485,7 +12834,7 @@ \indexlibrarymember{empty}{hazard_pointer}% \begin{itemdecl} -[[nodiscard]] bool empty() const noexcept; +bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} diff --git a/source/time.tex b/source/time.tex index aa4addb0fd..53af234aa4 100644 --- a/source/time.tex +++ b/source/time.tex @@ -198,23 +198,23 @@ // \ref{time.point.comparisons}, \tcode{time_point} comparisons template - constexpr bool operator==(const time_point& lhs, - const time_point& rhs); + constexpr bool operator==(const time_point& lhs, + const time_point& rhs); template - constexpr bool operator< (const time_point& lhs, - const time_point& rhs); + constexpr bool operator< (const time_point& lhs, + const time_point& rhs); template - constexpr bool operator> (const time_point& lhs, - const time_point& rhs); + constexpr bool operator> (const time_point& lhs, + const time_point& rhs); template - constexpr bool operator<=(const time_point& lhs, - const time_point& rhs); + constexpr bool operator<=(const time_point& lhs, + const time_point& rhs); template - constexpr bool operator>=(const time_point& lhs, - const time_point& rhs); + constexpr bool operator>=(const time_point& lhs, + const time_point& rhs); template Duration2> - constexpr auto operator<=>(const time_point& lhs, - const time_point& rhs); + constexpr auto operator<=>(const time_point& lhs, + const time_point& rhs); // \ref{time.point.cast}, conversions template @@ -857,7 +857,7 @@ // \ref{time.parse}, parsing template @\unspec@ - parse(const charT* fmt, Parsable& tp); + parse(const charT* fmt, Parsable& tp); template @\unspec@ parse(const basic_string& fmt, Parsable& tp); @@ -1036,7 +1036,7 @@ \end{note} \pnum -A type \tcode{TC} meets the \defnoldconcept{TrivialClock} requirements if: +A type \tcode{TC} meets the \defnoldconcept{TrivialClock} requirements if \begin{itemize} \item \tcode{TC} meets the \oldconcept{Clock} requirements, @@ -1183,7 +1183,7 @@ floating-point durations can have round-off errors. \end{note} -\indexlibraryglobal{common_type}% +\indexlibrarymember{common_type}{duration}% \begin{itemdecl} template struct common_type, chrono::time_point> { @@ -1601,7 +1601,7 @@ In the function descriptions that follow, unless stated otherwise, let \tcode{CD} represent the return type of the function. -\indexlibraryglobal{common_type}% +\indexlibrarymember{operator+}{duration}% \begin{itemdecl} template constexpr common_type_t, duration> @@ -1614,11 +1614,11 @@ \tcode{CD(CD(lhs).count() + CD(rhs).count())}. \end{itemdescr} -\indexlibraryglobal{common_type}% +\indexlibrarymember{operator-}{duration}% \begin{itemdecl} template constexpr common_type_t, duration> - operator-(const duration& lhs, const duration& rhs); + operator-(const duration& lhs, const duration& rhs); \end{itemdecl} \begin{itemdescr} @@ -2655,8 +2655,8 @@ static time_point now() noexcept; // mapping to/from C type \tcode{time_t} - static time_t to_time_t (const time_point& t) noexcept; - static time_point from_time_t(time_t t) noexcept; + static time_t to_time_t (const time_point& t) noexcept; + static time_point from_time_t(time_t t) noexcept; }; } \end{codeblock} @@ -3921,7 +3921,7 @@ \rSec1[time.cal]{The civil calendar} -\rSec2[time.cal.general]{In general} +\rSec2[time.cal.general]{General} \pnum The types in \ref{time.cal} describe the civil (Gregorian) calendar @@ -5404,7 +5404,7 @@ class weekday_last { chrono::weekday wd_; // \expos - public: + public: constexpr explicit weekday_last(const chrono::weekday& wd) noexcept; constexpr chrono::weekday weekday() const noexcept; @@ -8638,8 +8638,8 @@ \begin{itemdecl} template -basic_ostream& -operator<<(basic_ostream& os, const hh_mm_ss& hms); + basic_ostream& + operator<<(basic_ostream& os, const hh_mm_ss& hms); \end{itemdecl} \begin{itemdescr} @@ -8732,7 +8732,7 @@ \rSec1[time.zone]{Time zones} -\rSec2[time.zone.general]{In general} +\rSec2[time.zone.general]{General} \pnum \ref{time.zone} describes an interface for accessing @@ -10652,11 +10652,13 @@ Equivalent to \tcode{\%Y-\%m-\%d}. \\ \rowsep \tcode{\%g} & -The last two decimal digits of the ISO week-based year. +The last two decimal digits of the calendar year +as specified in ISO 8601-1:2019 for the week calendar. If the result is a single digit it is prefixed by \tcode{0}. \\ \rowsep \tcode{\%G} & -The ISO week-based year as a decimal number. +The calendar year as a decimal number, +as specified in ISO 8601-1:2019 for the week calendar. If the result is less than four digits it is left-padded with \tcode{0} to four digits. \\ \rowsep @@ -10682,7 +10684,7 @@ the decimal number of \tcode{days} without padding. Otherwise, the day of the year as a decimal number. -Jan 1 is \tcode{001}. +January 1 is \tcode{001}. If the result is less than three digits, it is left-padded with \tcode{0} to three digits. \\ \rowsep @@ -10736,7 +10738,8 @@ Equivalent to \tcode{\%H:\%M:\%S}. \\ \rowsep \tcode{\%u} & -The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), +The calendar day of week as a decimal number (\tcode{1}-\tcode{7}), +as specified in ISO 8601-1:2019, where Monday is \tcode{1}. The modified command \tcode{\%Ou} produces the locale's alternative representation. @@ -10750,7 +10753,8 @@ the locale's alternative representation. \\ \rowsep \tcode{\%V} & -The ISO week-based week number as a decimal number. +The calendar week of year as a decimal number, +as specified in ISO 8601-1:2019 for the week calendar. If the result is a single digit, it is prefixed with \tcode{0}. The modified command \tcode{\%OV} produces the locale's alternative representation. @@ -10793,7 +10797,7 @@ the locale's alternative full year representation. \\ \rowsep \tcode{\%z} & -The offset from UTC as specified in ISO 8601-1:2019, subclause 5.3.4.1. +The offset from UTC as specified in ISO 8601-1:2019, 5.3.4.1. For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC\@. If the offset is zero, \tcode{+0000} is used. The modified commands \tcode{\%Ez} and \tcode{\%Oz} @@ -10824,6 +10828,27 @@ \end{codeblock} \end{example} +\pnum +For \tcode{chrono::duration} +the library only provides the following specialization +of \tcode{enable_nonlocking_formatter_optimization}: +\begin{codeblock} +template + constexpr bool enable_nonlocking_formatter_optimization< + chrono::duration> = + enable_nonlocking_formatter_optimization; +\end{codeblock} + +\pnum +For \tcode{chrono::zoned_time} +the library only provides the following specialization of +\tcode{enable_nonlocking_formatter_optimization}: +\begin{codeblock} +template + constexpr bool enable_nonlocking_formatter_optimization< + chrono::zoned_time> = true; +\end{codeblock} + \indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::sys_time}}% \begin{itemdecl} template @@ -10969,6 +10994,9 @@ \pnum \remarks +If the \fmtgrammarterm{chrono-specs} is omitted, +the result is equivalent to using \tcode{\%F \%T \%Z} as +the \fmtgrammarterm{chrono-specs}. If \tcode{\%Z} is used, it is replaced with \tcode{*f.abbrev} if \tcode{f.abbrev} is not a null pointer value. @@ -10987,7 +11015,7 @@ \begin{codeblock} template struct formatter, charT> - : formatter, charT> { + : formatter>, charT> { template typename FormatContext::iterator format(const chrono::zoned_time& tp, FormatContext& ctx) const; @@ -11007,7 +11035,7 @@ Equivalent to: \begin{codeblock} sys_info info = tp.get_info(); -return formatter, charT>:: +return formatter>, charT>:: format({tp.get_local_time(), &info.abbrev, &info.offset}, ctx); \end{codeblock} \end{itemdescr} @@ -11268,14 +11296,16 @@ the width is applied to only \tcode{\%Y}. \\ \rowsep \tcode{\%g} & -The last two decimal digits of the ISO week-based year. +The last two decimal digits of the calendar year, +as specified in ISO 8601-1:2019 for the week calendar. The modified command \tcode{\%\placeholder{N}g} specifies the maximum number of characters to read. If \tcode{\placeholder{N}} is not specified, the default is 2. Leading zeroes are permitted but not required. \\ \rowsep \tcode{\%G} & -The ISO week-based year as a decimal number. +The calendar year as a decimal number, +as specified in ISO 8601-1:2019 for the week calendar. The modified command \tcode{\%\placeholder{N}G} specifies the maximum number of characters to read. If \tcode{\placeholder{N}} is not specified, the default is 4. @@ -11307,7 +11337,7 @@ a decimal number of \tcode{days}. Otherwise, the day of the year as a decimal number. -Jan 1 is \tcode{1}. +January 1 is \tcode{1}. In either case, the modified command \tcode{\%\placeholder{N}j} specifies the maximum number of characters to read. @@ -11316,7 +11346,7 @@ \\ \rowsep \tcode{\%m} & The month as a decimal number. -Jan is \tcode{1}. +January is \tcode{1}. The modified command \tcode{\%\placeholder{N}m} specifies the maximum number of characters to read. If \tcode{\placeholder{N}} is not specified, the default is 2. @@ -11373,7 +11403,9 @@ Equivalent to \tcode{\%H:\%M:\%S}. \\ \rowsep \tcode{\%u} & -The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), where Monday is \tcode{1}. +The calendar day of week as a decimal number (\tcode{1}-\tcode{7}), +as specified in ISO 8601-1:2019, +where Monday is \tcode{1}. The modified command \tcode{\%\placeholder{N}u} specifies the maximum number of characters to read. If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}. @@ -11391,7 +11423,8 @@ the locale's alternative representation. \\ \rowsep \tcode{\%V} & -The ISO week-based week number as a decimal number. +The calendar week of year as a decimal number, +as specified in ISO 8601-1:2019 for the week calendar. The modified command \tcode{\%\placeholder{N}V} specifies the maximum number of characters to read. If \tcode{\placeholder{N}} is not specified, the default is 2. @@ -11573,9 +11606,6 @@ \rSec1[ctime.syn]{Header \tcode{} synopsis} \indexheader{ctime}% -\indexlibraryglobal{CLOCKS_PER_SEC}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{TIME_UTC}% \indexlibraryglobal{asctime}% \indexlibraryglobal{clock_t}% \indexlibraryglobal{clock}% @@ -11592,9 +11622,9 @@ \indexlibraryglobal{time}% \indexlibraryglobal{tm}% \begin{codeblock} -#define NULL @\textit{see \ref{support.types.nullptr}}@ -#define CLOCKS_PER_SEC @\seebelow@ -#define TIME_UTC @\seebelow@ +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ +#define @\libmacro{CLOCKS_PER_SEC}@ @\seebelow@ +#define @\libmacro{TIME_UTC}@ @\seebelow@ namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; diff --git a/source/uax31.tex b/source/uax31.tex index aea6e6b5ba..641ab63b11 100644 --- a/source/uax31.tex +++ b/source/uax31.tex @@ -7,25 +7,27 @@ This Annex describes the choices made in application of \UAX{31} (``Unicode Identifier and Pattern Syntax'') to \Cpp{} in terms of the requirements from \UAX{31} and -how they do or do not apply to \Cpp{}. +how they do or do not apply to this document. In terms of \UAX{31}, -\Cpp{} conforms by meeting the requirements +this document conforms by meeting the requirements R1 ``Default Identifiers'' and -R4 ``Equivalent Normalized Identifiers''. -The other requirements, also listed below, -are either alternatives not taken or do not apply to \Cpp{}. +R4 ``Equivalent Normalized Identifiers'' from \UAX{31}. +The other requirements from \UAX{31}, also listed below, +are either alternatives not taken or do not apply to this document. \rSec1[uaxid.def]{R1 Default identifiers} \rSec2[uaxid.def.general]{General} +\indextext{XID_Start}% +\indextext{XID_Continue}% \pnum \UAX{31} specifies a default syntax for identifiers based on properties from the Unicode Character Database, \UAX{44}. The general syntax is -\begin{codeblock} +\begin{outputblock} := * ( +)* -\end{codeblock} +\end{outputblock} where \tcode{} has the XID_Start property, \tcode{} has the XID_Continue property, and \tcode{} is a list of characters permitted between continue characters. @@ -34,11 +36,11 @@ the \tcode{} set is empty, and the \tcode{} characters are unmodified. In the grammar used in \UAX{31}, this is -\begin{codeblock} +\begin{outputblock} := * := XID_Start + @\textrm{\ucode{005f}}@ := + XID_Continue -\end{codeblock} +\end{outputblock} \pnum This is described in the \Cpp{} grammar in \ref{lex.name}, @@ -91,7 +93,7 @@ during the processes of lexing and parsing. \pnum -\Cpp{} does not claim conformance with this requirement. +This document does not claim conformance with this requirement from \UAX{31}. \rSec1[uaxid.eqn]{R4 Equivalent normalized identifiers} @@ -100,16 +102,16 @@ how identifiers are compared and considered equivalent. \pnum -\Cpp{} requires that identifiers be in Normalization Form C and +This document requires that identifiers be in Normalization Form C and therefore identifiers that compare the same under NFC are equivalent. This is described in \ref{lex.name}. \rSec1[uaxid.eqci]{R5 Equivalent case-insensitive identifiers} \pnum -\Cpp{} considers case to be significant in identifier comparison, and +This document considers case to be significant in identifier comparison, and does not do any case folding. -This requirement does not apply to \Cpp{}. +This requirement from \UAX{31} does not apply to this document. \rSec1[uaxid.filter]{R6 Filtered normalized identifiers} @@ -118,15 +120,15 @@ \UAX{31} requires a precise specification of those exclusions. \pnum -\Cpp{} does not make any such exclusions. +This document does not make any such exclusions. \rSec1[uaxid.filterci]{R7 Filtered case-insensitive identifiers} \pnum \Cpp{} identifiers are case sensitive, and -therefore this requirement does not apply. +therefore this requirement from \UAX{31} does not apply. \rSec1[uaxid.hashtag]{R8 Hashtag identifiers} \pnum -There are no hashtags in \Cpp{}, so this requirement does not apply. +There are no hashtags in \Cpp{}, so this requirement from \UAX{31} does not apply. diff --git a/source/utilities.tex b/source/utilities.tex index f856a423b4..5172585905 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 @@ -98,8 +93,9 @@ template constexpr underlying_type_t to_underlying(T value) noexcept; - // \ref{utility.unreachable}, unreachable + // \ref{utility.undefined}, undefined behavior [[noreturn]] void unreachable(); + void observable() noexcept; // \ref{intseq}, compile-time integer sequences% \indexlibraryglobal{index_sequence}% @@ -225,6 +221,21 @@ explicit nontype_t() = default; }; template constexpr nontype_t nontype{}; + + // \ref{variant.monostate}, class \tcode{monostate}% +\indexlibraryglobal{monostate} + struct monostate; + + // \ref{variant.monostate.relops}, \tcode{monostate} relational operators% +\indexlibrarymember{operator==}{monostate}% +\indexlibrarymember{operator<=>}{monostate} + constexpr bool operator==(monostate, monostate) noexcept; + constexpr strong_ordering operator<=>(monostate, monostate) noexcept; + + // \ref{variant.hash}, hash support% +\indexlibrarymember{hash}{monostate} + template struct hash; + template<> struct hash; } \end{codeblock} @@ -372,7 +383,7 @@ \indexlibraryglobal{forward_like}% \begin{itemdecl} template - [[nodiscard]] constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; + constexpr auto forward_like(U&& x) noexcept -> @\seebelow@; \end{itemdecl} \begin{itemdescr} @@ -675,7 +686,7 @@ \tcode{static_cast>(value)}. \end{itemdescr} -\rSec2[utility.unreachable]{Function \tcode{unreachable}} +\rSec2[utility.undefined]{Undefined behavior} \indexlibraryglobal{unreachable}% \begin{itemdecl} @@ -709,9 +720,20 @@ \end{example} \end{itemdescr} +\indexlibraryglobal{observable}% +\begin{itemdecl} +void observable() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Establishes an observable checkpoint\iref{intro.abstract}. +\end{itemdescr} + \rSec1[pairs]{Pairs} -\rSec2[pairs.general]{In general} +\rSec2[pairs.general]{General} \pnum The library provides a template for heterogeneous pairs of values. @@ -1482,7 +1504,7 @@ \rSec1[tuple]{Tuples} -\rSec2[tuple.general]{In general} +\rSec2[tuple.general]{General} \pnum \indexlibraryglobal{tuple}% @@ -1494,6 +1516,11 @@ two arguments is similar to an instantiation of \tcode{pair} with the same two arguments. See~\ref{pairs}. +\pnum +In addition to being available via inclusion of the \libheader{tuple} header, +\tcode{ignore}\iref{tuple.syn} is available when +\libheader{utility}\iref{utility} is included. + \rSec2[tuple.syn]{Header \tcode{} synopsis} \indexheader{tuple}% @@ -1520,9 +1547,14 @@ template<@\exposconceptnc{tuple-like}@ TTuple, @\exposconceptnc{tuple-like}@ UTuple> struct common_type; - // \ref{tuple.creation}, tuple creation functions - inline constexpr @\unspec@ ignore; + // \tcode{ignore} + struct @\exposidnc{ignore-type}@ { // \expos + constexpr const @\exposid{ignore-type}@& + operator=(const auto &) const noexcept { return *this; } + }; + inline constexpr @\exposid{ignore-type}@ ignore; + // \ref{tuple.creation}, tuple creation functions template constexpr tuple...> make_tuple(TTypes&&...); @@ -2435,7 +2467,7 @@ \item \tcode{sizeof...(Types)} -equals \tcode{tuple_size_v>}, and, +equals \tcode{tuple_size_v>}, and \item \tcode{is_assignable_v<$\tcode{T}_i$\&, decltype(get<$i$>(std::forward(u)))>} @@ -2472,7 +2504,7 @@ \item \tcode{sizeof...(Types)} -equals \tcode{tuple_size_v>}, and, +equals \tcode{tuple_size_v>}, and \item \tcode{is_assignable_v(std::forward(u)))>} @@ -2591,9 +2623,7 @@ \begin{itemdescr} \pnum \returns -\tcode{tuple(t...)}. When an -argument in \tcode{t} is \tcode{ignore}, assigning -any value to the corresponding tuple element has no effect. +\tcode{tuple(t...)}. \pnum \begin{example} @@ -2748,7 +2778,7 @@ \indexlibraryglobal{tuple_size}% \begin{itemdecl} template - struct tuple_size> : public integral_constant { }; + struct tuple_size> : integral_constant { }; \end{itemdecl} \indexlibraryglobal{tuple_element}% @@ -2840,10 +2870,10 @@ get(tuple& t) noexcept; template constexpr tuple_element_t>&& - get(tuple&& t) noexcept; // Note A + get(tuple&& t) noexcept; // \#1 template constexpr const tuple_element_t>& - get(const tuple& t) noexcept; // Note B + get(const tuple& t) noexcept; // \#2 template constexpr const tuple_element_t>&& get(const tuple&& t) noexcept; \end{itemdecl} @@ -2860,8 +2890,8 @@ \pnum \begin{note} -[Note A] -If a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, +For the overload marked \#1, +if a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, the return type is \tcode{X\&}, not \tcode{X\&\&}. However, if the element type is a non-reference type \tcode{T}, the return type is \tcode{T\&\&}. @@ -2869,9 +2899,9 @@ \pnum \begin{note} -[Note B] Constness is shallow. -If a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, +For the overload marked \#2, +if a type \tcode{T} in \tcode{Types} is some reference type \tcode{X\&}, the return type is \tcode{X\&}, not \tcode{const X\&}. However, if the element type is a non-reference type \tcode{T}, the return type is \tcode{const T\&}. @@ -3144,7 +3174,7 @@ \rSec1[optional]{Optional objects} -\rSec2[optional.general]{In general} +\rSec2[optional.general]{General} \pnum Subclause~\ref{optional} describes class template \tcode{optional} that represents @@ -3168,6 +3198,11 @@ template class optional; // partially freestanding + template + constexpr bool ranges::enable_view> = true; + template + constexpr auto format_kind> = range_format::disabled; + template concept @\defexposconcept{is-derived-from-optional}@ = requires(const T& t) { // \expos [](const optional&){ }(t); @@ -3225,7 +3260,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 @@ -3248,7 +3283,9 @@ template class optional { public: - using value_type = T; + using value_type = T; + using iterator = @\impdefnc@; // see~\ref{optional.iterators} + using const_iterator = @\impdefnc@; // see~\ref{optional.iterators} // \ref{optional.ctor}, constructors constexpr optional() noexcept; @@ -3259,7 +3296,7 @@ constexpr explicit optional(in_place_t, Args&&...); template constexpr explicit optional(in_place_t, initializer_list, Args&&...); - template + template> constexpr explicit(@\seebelow@) optional(U&&); template constexpr explicit(@\seebelow@) optional(const optional&); @@ -3273,7 +3310,7 @@ constexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional&); constexpr optional& operator=(optional&&) noexcept(@\seebelow@); - template constexpr optional& operator=(U&&); + template> constexpr optional& operator=(U&&); template constexpr optional& operator=(const optional&); template constexpr optional& operator=(optional&&); template constexpr T& emplace(Args&&...); @@ -3282,6 +3319,12 @@ // \ref{optional.swap}, swap constexpr void swap(optional&) noexcept(@\seebelow@); + // \ref{optional.iterators}, iterator support + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + // \ref{optional.observe}, observers constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; @@ -3295,8 +3338,8 @@ constexpr T& value() &; // freestanding-deleted constexpr T&& value() &&; // freestanding-deleted constexpr const T&& value() const &&; // freestanding-deleted - template constexpr T value_or(U&&) const &; - template constexpr T value_or(U&&) &&; + template> constexpr T value_or(U&&) const &; + template> constexpr T value_or(U&&) &&; // \ref{optional.monadic}, monadic operations template constexpr auto and_then(F&& f) &; @@ -3314,7 +3357,7 @@ constexpr void reset() noexcept; private: - T *val; // \expos + T* val; // \expos }; template @@ -3326,8 +3369,7 @@ Any instance of \tcode{optional} at any given time either contains a value or does not contain a value. When an instance of \tcode{optional} \defnx{contains a value}{contains a value!\idxcode{optional}}, it means that an object of type \tcode{T}, referred to as the optional object's \defnx{contained value}{contained value!\idxcode{optional}}, -is allocated within the storage of the optional object. -Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. +is nested within\iref{intro.object} the optional object. When an object of type \tcode{optional} is contextually converted to \tcode{bool}, the conversion returns \tcode{true} if the object contains a value; otherwise the conversion returns \tcode{false}. @@ -3488,7 +3530,7 @@ \indexlibraryctor{optional}% \begin{itemdecl} -template constexpr explicit(@\seebelow@) optional(U&& v); +template> constexpr explicit(@\seebelow@) optional(U&& v); \end{itemdecl} \begin{itemdescr} @@ -3740,16 +3782,18 @@ \indexlibrarymember{operator=}{optional}% \begin{itemdecl} -template constexpr optional& operator=(U&& v); +template> constexpr optional& operator=(U&& v); \end{itemdecl} \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 @@ -4001,6 +4045,59 @@ the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move constructor. \end{itemdescr} +\rSec3[optional.iterators]{Iterator support} + +\indexlibrarymember{iterator}{optional}% +\indexlibrarymember{const_iterator}{optional}% +\begin{itemdecl} +using iterator = @\impdef@; +using const_iterator = @\impdef@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +These types +model \libconcept{contiguous_iterator}\iref{iterator.concept.contiguous}, +meet the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}, and +meet the requirements for constexpr iterators\iref{iterator.requirements.general}, +with value type \tcode{remove_cv_t}. +The reference type is \tcode{T\&} for \tcode{iterator} and +\tcode{const T\&} for \tcode{const_iterator}. + +\pnum +All requirements on container iterators\iref{container.reqmts} apply to +\tcode{optional::iterator} and \tcode{optional::\linebreak{}const_iterator} as well. + +\pnum +Any operation that initializes or destroys the contained value of an optional object invalidates all iterators into that object. +\end{itemdescr} + +\indexlibrarymember{begin}{optional}% +\begin{itemdecl} +constexpr iterator begin() noexcept; +constexpr const_iterator begin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{has_value()} is \tcode{true}, +an iterator referring to the contained value. +Otherwise, a past-the-end iterator value. +\end{itemdescr} + +\indexlibrarymember{end}{optional}% +\begin{itemdecl} +constexpr iterator end() noexcept; +constexpr const_iterator end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{begin() + has_value()}. +\end{itemdescr} + \rSec3[optional.observe]{Observers} \indexlibrarymember{operator->}{optional}% @@ -4011,8 +4108,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \returns @@ -4031,8 +4128,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \returns @@ -4051,8 +4148,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \effects @@ -4122,7 +4219,7 @@ \indexlibrarymember{value_or}{optional}% \begin{itemdecl} -template constexpr T value_or(U&& v) const &; +template> constexpr T value_or(U&& v) const &; \end{itemdecl} \begin{itemdescr} @@ -4140,7 +4237,7 @@ \indexlibrarymember{value_or}{optional}% \begin{itemdecl} -template constexpr T value_or(U&& v) &&; +template> constexpr T value_or(U&& v) &&; \end{itemdecl} \begin{itemdescr} @@ -4281,7 +4378,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{F} models \tcode{\libconcept{invocable}<>} and +\tcode{F} models \libconcept{invocable} and \tcode{T} models \libconcept{copy_constructible}. \pnum @@ -4308,7 +4405,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{F} models \tcode{\libconcept{invocable}<>} and +\tcode{F} models \libconcept{invocable} and \tcode{T} models \libconcept{move_constructible}. \pnum @@ -4369,7 +4466,7 @@ class bad_optional_access : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -4379,13 +4476,15 @@ \indexlibrarymember{what}{bad_optional_access}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_optional_access::what}} \ntbs{}. +An \impldef{return value of \tcode{bad_optional_access::what}} \ntbs{}, +which during constant evaluation is encoded with +the ordinary literal encoding\iref{lex.ccon}. \end{itemdescr} \rSec2[optional.relops]{Relational operators} @@ -4588,6 +4687,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x == v} is well-formed and its result is convertible to \tcode{bool}. \begin{note} @@ -4607,6 +4707,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v == *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4623,6 +4724,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x != v} is well-formed and its result is convertible to \tcode{bool}. @@ -4639,6 +4741,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v != *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4655,6 +4758,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x < v} is well-formed and its result is convertible to \tcode{bool}. @@ -4671,6 +4775,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v < *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4687,6 +4792,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x > v} is well-formed and its result is convertible to \tcode{bool}. @@ -4703,6 +4809,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v > *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4719,6 +4826,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x <= v} is well-formed and its result is convertible to \tcode{bool}. @@ -4735,6 +4843,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v <= *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4751,6 +4860,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{U} is not a specialization of \tcode{optional}. The expression \tcode{*x >= v} is well-formed and its result is convertible to \tcode{bool}. @@ -4767,6 +4877,7 @@ \begin{itemdescr} \pnum \constraints +\tcode{T} is not a specialization of \tcode{optional}. The expression \tcode{v >= *x} is well-formed and its result is convertible to \tcode{bool}. @@ -4864,7 +4975,7 @@ \rSec1[variant]{Variants} -\rSec2[variant.general]{In general} +\rSec2[variant.general]{General} \pnum A variant object holds and manages the lifetime of a value. @@ -4873,7 +4984,7 @@ These template arguments are called alternatives. \pnum -In subclause \ref{variant}, +In \ref{variant}, \exposid{GET} denotes a set of exposition-only function templates\iref{variant.get}. @@ -5061,10 +5172,9 @@ of one of its alternative types or holds no value. When an instance of \tcode{variant} holds a value of alternative type \tcode{T}, it means that a value of type \tcode{T}, referred to as the \tcode{variant} -object's \defnx{contained value}{contained value!\idxcode{variant}}, is allocated within the storage of the +object's \defnx{contained value}{contained value!\idxcode{variant}}, +is nested within\iref{intro.object} the \tcode{variant} object. -Implementations are not permitted to use additional storage, such as dynamic -memory, to allocate the contained value. \pnum All types in \tcode{Types} shall meet @@ -6141,13 +6251,13 @@ Let \exposid{as-variant} denote the following exposition-only function templates: \begin{codeblock} template - auto&& @\exposid{as-variant}@(variant& var) { return var; } + constexpr auto&& @\exposid{as-variant}@(variant& var) { return var; } template - auto&& @\exposid{as-variant}@(const variant& var) { return var; } + constexpr auto&& @\exposid{as-variant}@(const variant& var) { return var; } template - auto&& @\exposid{as-variant}@(variant&& var) { return std::move(var); } + constexpr auto&& @\exposid{as-variant}@(variant&& var) { return std::move(var); } template - auto&& @\exposid{as-variant}@(const variant&& var) { return std::move(var); } + constexpr auto&& @\exposid{as-variant}@(const variant&& var) { return std::move(var); } \end{codeblock} Let $n$ be \tcode{sizeof...(Variants)}. For each $0 \leq i < n$, let @@ -6303,7 +6413,7 @@ class bad_variant_access : public exception { public: // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} @@ -6314,13 +6424,15 @@ \indexlibrarymember{what}{bad_variant_access}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns -An \impldef{return value of \tcode{bad_variant_access::what}} \ntbs{}. +An \impldef{return value of \tcode{bad_variant_access::what}} \ntbs{}, +which during constant evaluation is encoded with +the ordinary literal encoding\iref{lex.ccon}. \end{itemdescr} \rSec2[variant.hash]{Hash support} @@ -6985,7 +7097,7 @@ \rSec1[expected]{Expected objects} \indexlibraryglobal{expected}% -\rSec2[expected.general]{In general} +\rSec2[expected.general]{General} \pnum Subclause \ref{expected} describes the class template \tcode{expected} @@ -7236,12 +7348,12 @@ template class bad_expected_access : public bad_expected_access { public: - explicit bad_expected_access(E); - const char* what() const noexcept override; - E& error() & noexcept; - const E& error() const & noexcept; - E&& error() && noexcept; - const E&& error() const && noexcept; + constexpr explicit bad_expected_access(E); + constexpr const char* what() const noexcept override; + constexpr E& error() & noexcept; + constexpr const E& error() const & noexcept; + constexpr E&& error() && noexcept; + constexpr const E&& error() const && noexcept; private: E @\exposidnc{unex}@; // \expos @@ -7257,7 +7369,7 @@ \indexlibraryctor{bad_expected_access}% \begin{itemdecl} -explicit bad_expected_access(E e); +constexpr explicit bad_expected_access(E e); \end{itemdecl} \begin{itemdescr} @@ -7268,8 +7380,8 @@ \indexlibrarymember{error}{bad_expected_access}% \begin{itemdecl} -const E& error() const & noexcept; -E& error() & noexcept; +constexpr const E& error() const & noexcept; +constexpr E& error() & noexcept; \end{itemdecl} \begin{itemdescr} @@ -7280,8 +7392,8 @@ \indexlibrarymember{error}{bad_expected_access}% \begin{itemdecl} -E&& error() && noexcept; -const E&& error() const && noexcept; +constexpr E&& error() && noexcept; +constexpr const E&& error() const && noexcept; \end{itemdecl} \begin{itemdescr} @@ -7292,13 +7404,15 @@ \indexlibrarymember{what}{bad_expected_access}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns -An implementation-defined \ntbs. +An \impldef{return value of \tcode{bad_expected_access::what}} \ntbs, +which during constant evaluation is encoded with +the ordinary literal encoding\iref{lex.ccon}. \end{itemdescr} \rSec2[expected.bad.void]{Class template specialization \tcode{bad_expected_access}} @@ -7308,28 +7422,30 @@ template<> class bad_expected_access : public exception { protected: - bad_expected_access() noexcept; - bad_expected_access(const bad_expected_access&) noexcept; - bad_expected_access(bad_expected_access&&) noexcept; - bad_expected_access& operator=(const bad_expected_access& noexcept); - bad_expected_access& operator=(bad_expected_access&&) noexcept; - ~bad_expected_access(); + constexpr bad_expected_access() noexcept; + constexpr bad_expected_access(const bad_expected_access&) noexcept; + constexpr bad_expected_access(bad_expected_access&&) noexcept; + constexpr bad_expected_access& operator=(const bad_expected_access&) noexcept; + constexpr bad_expected_access& operator=(bad_expected_access&&) noexcept; + constexpr ~bad_expected_access(); public: - const char* what() const noexcept override; + constexpr const char* what() const noexcept override; }; } \end{codeblock} \indexlibrarymember{what}{bad_expected_access}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns -An implementation-defined \ntbs. +An \impldef{return value of \tcode{bad_expected_access::what}} \ntbs, +which during constant evaluation is encoded with +the ordinary literal encoding\iref{lex.ccon}. \end{itemdescr} \rSec2[expected.expected]{Class template \tcode{expected}} @@ -7357,7 +7473,7 @@ template constexpr explicit(@\seebelow@) expected(expected&&); - template + template> constexpr explicit(@\seebelow@) expected(U&& v); template @@ -7380,7 +7496,7 @@ // \ref{expected.object.assign}, assignment constexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(@\seebelow@); - template constexpr expected& operator=(U&&); + template> constexpr expected& operator=(U&&); template constexpr expected& operator=(const unexpected&); template @@ -7412,8 +7528,8 @@ constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; - template constexpr T value_or(U&&) const &; - template constexpr T value_or(U&&) &&; + template> constexpr T value_or(U&&) const &; + template> constexpr T value_or(U&&) &&; template constexpr E error_or(G&&) const &; template constexpr E error_or(G&&) &&; @@ -7456,10 +7572,8 @@ \pnum Any object of type \tcode{expected} either contains a value of type \tcode{T} or -a value of type \tcode{E} within its own storage. -Implementations are not permitted to use additional storage, -such as dynamic memory, -to allocate the object of type \tcode{T} or the object of type \tcode{E}. +a value of type \tcode{E} +nested within\iref{intro.object} it. Member \exposid{has_val} indicates whether the \tcode{expected} object contains an object of type \tcode{T}. @@ -7664,7 +7778,7 @@ \indexlibraryctor{expected}% \begin{itemdecl} -template +template> constexpr explicit(!is_convertible_v) expected(U&& v); \end{itemdecl} @@ -7983,7 +8097,7 @@ \indexlibrarymember{operator=}{expected}% \begin{itemdecl} -template +template> constexpr expected& operator=(U&& v); \end{itemdecl} @@ -8222,7 +8336,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8238,7 +8352,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8254,7 +8368,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8325,7 +8439,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -8341,7 +8455,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -8351,7 +8465,7 @@ \indexlibrarymember{value_or}{expected}% \begin{itemdecl} -template constexpr T value_or(U&& v) const &; +template> constexpr T value_or(U&& v) const &; \end{itemdecl} \begin{itemdescr} @@ -8367,7 +8481,7 @@ \indexlibrarymember{value_or}{expected}% \begin{itemdecl} -template constexpr T value_or(U&& v) &&; +template> constexpr T value_or(U&& v) &&; \end{itemdecl} \begin{itemdescr} @@ -8696,7 +8810,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expressions \tcode{*x == *y} and \tcode{x.error() == y.error()} are well-formed and their results are convertible to \tcode{bool}. @@ -8714,7 +8828,8 @@ \begin{itemdescr} \pnum -\mandates +\constraints +\tcode{T2} is not a specialization of \tcode{expected}. The expression \tcode{*x == v} is well-formed and its result is convertible to \tcode{bool}. \begin{note} @@ -8733,7 +8848,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{x.error() == e.error()} is well-formed and its result is convertible to \tcode{bool}. @@ -8842,9 +8957,8 @@ \pnum Any object of type \tcode{expected} either represents a value of type \tcode{T}, or -contains a value of type \tcode{E} within its own storage. -Implementations are not permitted to use additional storage, -such as dynamic memory, to allocate the object of type \tcode{E}. +contains a value of type \tcode{E} +nested within\iref{intro.object} it. Member \exposid{has_val} indicates whether the \tcode{expected} object represents a value of type \tcode{T}. @@ -9050,7 +9164,7 @@ \indexlibraryctor{expected}% \begin{itemdecl} template - constexpr explicit expected(unexpect_t, initializer_list il, Args&&... args); + constexpr explicit expected(unexpect_t, initializer_list il, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -9293,7 +9407,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \end{itemdescr} @@ -9337,7 +9451,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -9353,7 +9467,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -9655,7 +9769,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{x.error() == y.error()} is well-formed and its result is convertible to \tcode{bool}. @@ -9673,7 +9787,7 @@ \begin{itemdescr} \pnum -\mandates +\constraints The expression \tcode{x.error() == e.error()} is well-formed and its result is convertible to \tcode{bool}. @@ -9725,9 +9839,6 @@ public: // bit reference class reference { - friend class bitset; - constexpr reference() noexcept; - public: constexpr reference(const reference&) = default; constexpr ~reference(); @@ -10230,8 +10341,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos} is valid. +\hardexpects +\tcode{pos < size()} is \tcode{true}. \pnum \returns @@ -10250,8 +10361,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos} is valid. +\hardexpects +\tcode{pos < size()} is \tcode{true}. \pnum \returns @@ -10687,9 +10798,7 @@ // \tcode{\placeholder{M}} is the \impldef{number of placeholders for bind expressions} number of placeholders @\seebelownc@ _1; // freestanding @\seebelownc@ _2; // freestanding - . - . - . + @\vdots@ @\seebelownc@ _@\placeholdernc{M}@; // freestanding } @@ -10755,6 +10864,25 @@ struct greater_equal; // freestanding struct less_equal; // freestanding } + + template + concept @\defexposconceptnc{callable}@ = // \expos + requires (Fn&& fn, Args&&... args) { + std::forward(fn)(std::forward(args)...); + }; + + template + concept @\defexposconceptnc{nothrow-callable}@ = // \expos + @\exposconcept{callable}@ && + requires (Fn&& fn, Args&&... args) { + { std::forward(fn)(std::forward(args)...) } noexcept; + }; + + template + using @\exposidnc{call-result-t}@ = decltype(declval()(declval()...)); // \expos + + template + using @\exposidnc{decayed-typeof}@ = decltype(auto(T)); // \expos } \end{codeblock} @@ -10825,7 +10953,7 @@ \item \tcode{(t$_1$.*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a member function of a class \tcode{T} and -\tcode{is_same_v> ||} +\tcode{is_same_v> ||} \tcode{is_base_of_v>} is \tcode{true}; \item \tcode{(t$_1$.get().*f)(t$_2$, $\dotsc$, t$_N$)} when \tcode{f} is a pointer to a @@ -10839,7 +10967,7 @@ \item \tcode{t$_1$.*f} when $N = 1$ and \tcode{f} is a pointer to data member of a class \tcode{T} and -\tcode{is_same_v> ||} +\tcode{is_same_v> ||} \tcode{is_base_of_v>} is \tcode{true}; \item \tcode{t$_1$.get().*f} when $N = 1$ and \tcode{f} is a pointer to @@ -11003,10 +11131,9 @@ friend constexpr bool operator==(reference_wrapper, const T&); friend constexpr bool operator==(reference_wrapper, reference_wrapper); - friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, reference_wrapper); - friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, const T&); - friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper, - reference_wrapper); + friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); + friend constexpr auto operator<=>(reference_wrapper, const T&); + friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); }; template @@ -11026,7 +11153,7 @@ The template parameter \tcode{T} of \tcode{reference_wrapper} may be an incomplete type. \begin{note} -Using the comparison operators described in subclause \ref{refwrap.comparisons} +Using the comparison operators described in \ref{refwrap.comparisons} with \tcode{T} being an incomplete type can lead to an ill-formed program with no diagnostic required\iref{temp.point,temp.constr.atomic}. @@ -11131,7 +11258,7 @@ \pnum \returns -\tcode{\placeholdernc{INVOKE}(get(), std::forward(args)...)}.\iref{func.require} +\tcode{\placeholdernc{INVOKE}(get(), std::forward(args)...)}\iref{func.require}. \end{itemdescr} \rSec3[refwrap.comparisons]{Comparisons} @@ -11183,34 +11310,45 @@ \end{itemdescr} \begin{itemdecl} -friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, reference_wrapper y); +friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper y); \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +The expression \tcode{\exposid{synth-three-way}(x.get(), y.get())} +is well-formed. + \pnum \returns \tcode{\exposid{synth-three-way}(x.get(), y.get())}. \end{itemdescr} \begin{itemdecl} -friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, const T& y); +friend constexpr auto operator<=>(reference_wrapper x, const T& y); \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +The expression \tcode{\exposid{synth-three-way}(x.get(), y)} +is well-formed. + \pnum \returns \tcode{\exposid{synth-three-way}(x.get(), y)}. \end{itemdescr} \begin{itemdecl} -friend constexpr @\exposidnc{synth-three-way-result}@ operator<=>(reference_wrapper x, - reference_wrapper y); +friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper y); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_const_v} is \tcode{false}. +The expression \tcode{\exposid{synth-three-way}(x.get(), y.get())} +is well-formed. \pnum \returns @@ -12629,7 +12767,7 @@ \end{itemize} \pnum -throws +\throws Any exception thrown by the initialization of \tcode{bound_args}. \end{itemdescr} @@ -12837,13 +12975,11 @@ % "namespace placeholders" in [functional.syn]? \begin{codeblock} namespace std::placeholders { - // M is the number of placeholders + // \tcode{\placeholder{M}} is the number of placeholders @\seebelow@ _1; @\seebelow@ _2; - . - . - . - @\seebelow@ _M; + @\itcorr\vdots@ + @\seebelow@ _@\placeholdernc{M}@; } \end{codeblock} @@ -13016,17 +13152,6 @@ and call arbitrary callable objects\iref{func.def}, given a call signature\iref{func.def}. -\pnum -\indextext{callable type}% -A callable type\iref{func.def} \tcode{F} -is \defn{Lvalue-Callable} for argument -types \tcode{ArgTypes} -and return type \tcode{R} -if the expression -\tcode{\placeholdernc{INVOKE}(declval(), declval()...)}, -considered as an unevaluated operand\iref{term.unevaluated.operand}, is -well-formed\iref{func.require}. - \pnum The \tcode{function} class template is a call wrapper\iref{func.def} whose call signature\iref{func.def} @@ -13071,7 +13196,7 @@ \pnum \ensures \tcode{!*this} if \tcode{!f}; otherwise, -the target object of \tcode{*this} is a copy of \tcode{f.target()}. +the target object of \tcode{*this} is a copy of the target object of \tcode{f}. \pnum \throws @@ -13124,8 +13249,7 @@ \item \tcode{is_same_v, function>} is \tcode{false}, and \item -\tcode{FD} is Lvalue-Callable\iref{func.wrap.func} for argument types -\tcode{ArgTypes...} and return type \tcode{R}. +\tcode{is_invocable_r_v} is \tcode{true}. \end{itemize} \pnum @@ -13268,8 +13392,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{decay_t} is Lvalue-Callable\iref{func.wrap.func} -for argument types \tcode{ArgTypes...} and return type \tcode{R}. +\tcode{is_invocable_r_v\&, ArgTypes...>} is \tcode{true}. \pnum \effects @@ -14312,7 +14435,7 @@ that models \libconcept{copyable}. \pnum -Within subclause \ref{func.wrap.ref}, +Within \ref{func.wrap.ref}, \tcode{\placeholder{call-args}} is an argument pack with elements such that \tcode{decltype((\placeholder{call-args}\linebreak{}))...} denote \tcode{Args\&\&...} respectively. @@ -14726,8 +14849,8 @@ \expects The value type of \tcode{RandomAccessIterator1} meets the \oldconcept{DefaultConstructible}, -the \oldconcept{Copy\-Constructible}, and -the \oldconcept{CopyAssignable} requirements. +\oldconcept{CopyConstructible}, and +\oldconcept{CopyAssignable} requirements. \pnum Let \tcode{V} be \tcode{iterator_traits::val\-ue_type}. @@ -14947,4113 +15070,142 @@ 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 behavior 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} - -\begin{itemdescr} -\pnum -\returns -\tcode{!rhs.target->before(*target)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{type_index}% -\begin{itemdecl} -bool operator>=(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{!target->before(*rhs.target)}. -\end{itemdescr} - -\indexlibrarymember{operator<=>}{type_index}% -\begin{itemdecl} -strong_ordering operator<=>(const type_index& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -if (*target == *rhs.target) return strong_ordering::equal; -if (target->before(*rhs.target)) return strong_ordering::less; -return strong_ordering::greater; -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{hash_code}{type_index}% -\begin{itemdecl} -size_t hash_code() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{target->hash_code()}. -\end{itemdescr} - -\indexlibrarymember{name}{type_index}% -\begin{itemdecl} -const char* name() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{target->name()}. -\end{itemdescr} - -\rSec2[type.index.hash]{Hash support} - -\indexlibrarymember{hash}{type_index}% -\begin{itemdecl} -template<> struct hash; -\end{itemdecl} - -\begin{itemdescr} -\pnum -For an object \tcode{index} of type \tcode{type_index}, -\tcode{hash()(index)} shall evaluate to the same result as \tcode{index.hash_code()}. -\end{itemdescr} - -\rSec1[execpol]{Execution policies} -\rSec2[execpol.general]{In 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. -\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 standard as extensions -to address parallel architectures that require idiosyncratic -parameters for efficient execution. -\end{note} - -\rSec2[execution.syn]{Header \tcode{} synopsis} - -\indexheader{execution}% -\begin{codeblock} -namespace std { - // \ref{execpol.type}, execution policy type trait - template struct is_execution_policy; - template constexpr bool @\libglobal{is_execution_policy_v}@ = is_execution_policy::value; -} - -namespace std::execution { - // \ref{execpol.seq}, sequenced execution policy - class sequenced_policy; - - // \ref{execpol.par}, parallel execution policy - class parallel_policy; - - // \ref{execpol.parunseq}, parallel and unsequenced execution policy - class parallel_unsequenced_policy; - - // \ref{execpol.unseq}, unsequenced execution policy - class unsequenced_policy; - - // \ref{execpol.objects}, execution policy objects - inline constexpr sequenced_policy seq{ @\unspec@ }; - inline constexpr parallel_policy par{ @\unspec@ }; - inline constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; - inline constexpr unsequenced_policy unseq{ @\unspec@ }; -} -\end{codeblock} - -\rSec2[execpol.type]{Execution policy type trait} - -\indexlibraryglobal{is_execution_policy}% -\begin{itemdecl} -template struct is_execution_policy { @\seebelow@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\tcode{is_execution_policy} can be used to detect execution policies for the -purpose of excluding function signatures from otherwise ambiguous overload -resolution participation. - -\pnum -\tcode{is_execution_policy} is a \oldconcept{UnaryTypeTrait} with a -base characteristic of \tcode{true_type} if \tcode{T} is the type of a standard -or \impldef{additional execution policies supported by parallel algorithms} -execution policy, otherwise \tcode{false_type}. - -\begin{note} -This provision reserves the privilege of creating non-standard execution -policies to the library implementation. -\end{note} - -\pnum -The behavior of a program that adds specializations for -\tcode{is_execution_policy} is undefined. -\end{itemdescr} - -\rSec2[execpol.seq]{Sequenced execution policy} - -\indexlibraryglobal{execution::sequenced_policy}% -\begin{itemdecl} -class execution::sequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::sequenced_policy} is an execution policy type used -as a unique type to disambiguate parallel algorithm overloading and require -that a parallel algorithm's execution may not be parallelized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::sequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.par]{Parallel execution policy} - -\indexlibraryglobal{execution::parallel_policy}% -\begin{itemdecl} -class execution::parallel_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::parallel_policy} is an execution policy type used as -a unique type to disambiguate parallel algorithm overloading and indicate that -a parallel algorithm's execution may be parallelized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::parallel_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.parunseq]{Parallel and unsequenced execution policy} - -\indexlibraryglobal{execution::parallel_unsequenced_policy}% -\begin{itemdecl} -class execution::parallel_unsequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{execution::parallel_unsequenced_policy} is an execution policy type -used as a unique type to disambiguate parallel algorithm overloading and -indicate that a parallel algorithm's execution may be parallelized and -vectorized. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::parallel_unsequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.unseq]{Unsequenced execution policy} - -\indexlibraryglobal{execution::unsequenced_policy}% -\begin{itemdecl} -class execution::unsequenced_policy { @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The class \tcode{unsequenced_policy} is an execution policy type -used as a unique type to disambiguate parallel algorithm overloading and -indicate that a parallel algorithm's execution may be vectorized, -e.g., executed on a single thread using instructions -that operate on multiple data items. - -\pnum -During the execution of a parallel algorithm with -the \tcode{execution::unsequenced_policy} policy, -if the invocation of an element access function exits via an exception, -\tcode{terminate} is invoked\iref{except.terminate}. -\end{itemdescr} - -\rSec2[execpol.objects]{Execution policy objects} - -\indexlibraryglobal{seq}% -\indexlibraryglobal{par}% -\indexlibraryglobal{par_unseq}% -\indexlibrarymember{execution}{seq}% -\indexlibrarymember{execution}{par}% -\indexlibrarymember{execution}{par_unseq}% -\begin{itemdecl} -inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; -inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; -inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; -inline constexpr execution::unsequenced_policy execution::unseq{ @\unspec@ }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -The header \libheader{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> { }; - - // \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]{In 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 -\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}% --based 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}. -In addition, -for each type \tcode{T} for which -a \tcode{formatter} specialization is provided above, -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} -and \tcode{formatter} -that would require implicit -multibyte / wide string or character conversion are disabled. -\end{note} - -\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 - - 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 get_char = [&]() { return iter != ctx.end() ? *iter : 0; }; - if (get_char() != '{') - return iter; - ++iter; - char c = get_char(); - if (!isdigit(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: - basic_format_args() noexcept; - - 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} -basic_format_args() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes \tcode{size_} with \tcode{0}. -\end{itemdescr} - -\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; - }; -} -\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 - [[nodiscard]] constexpr T rotl(T x, int s) noexcept; - template - [[nodiscard]] 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}. +\constraints +\tcode{T} models \libconcept{integral}. \pnum \mandates @@ -19169,7 +15321,7 @@ \begin{itemdecl} template - [[nodiscard]] constexpr T rotl(T x, int s) noexcept; + constexpr T rotl(T x, int s) noexcept; \end{itemdecl} \indexlibraryglobal{rotl}% @@ -19190,7 +15342,7 @@ \begin{itemdecl} template - [[nodiscard]] constexpr T rotr(T x, int s) noexcept; + constexpr T rotr(T x, int s) noexcept; \end{itemdecl} \indexlibraryglobal{rotr}% @@ -19347,95 +15499,131 @@ 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. +\rSec1[stdbit.h.syn]{Header \tcode{} synopsis} + +\indexheader{stdbit.h}% +\begin{codeblock} +#define @\libmacro{__STDC_VERSION_STDBIT_H__}@ 202311L + +#define @\libmacro{__STDC_ENDIAN_BIG__}@ @\seebelow@ +#define @\libmacro{__STDC_ENDIAN_LITTLE__}@ @\seebelow@ +#define @\libmacro{__STDC_ENDIAN_NATIVE__}@ @\seebelow@ + +unsigned int @\libglobal{stdc_leading_zeros_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_leading_zeros_us}@(unsigned short value); +unsigned int @\libglobal{stdc_leading_zeros_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_leading_zeros_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_leading_zeros_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_leading_zeros}@(T value); + +unsigned int @\libglobal{stdc_leading_ones_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_leading_ones_us}@(unsigned short value); +unsigned int @\libglobal{stdc_leading_ones_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_leading_ones_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_leading_ones_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_leading_ones}@(T value); + +unsigned int @\libglobal{stdc_trailing_zeros_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_trailing_zeros_us}@(unsigned short value); +unsigned int @\libglobal{stdc_trailing_zeros_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_trailing_zeros_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_trailing_zeros_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_trailing_zeros}@(T value); + +unsigned int @\libglobal{stdc_trailing_ones_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_trailing_ones_us}@(unsigned short value); +unsigned int @\libglobal{stdc_trailing_ones_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_trailing_ones_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_trailing_ones_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_trailing_ones}@(T value); + +unsigned int @\libglobal{stdc_first_leading_zero_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_first_leading_zero_us}@(unsigned short value); +unsigned int @\libglobal{stdc_first_leading_zero_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_first_leading_zero_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_first_leading_zero_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_first_leading_zero}@(T value); + +unsigned int @\libglobal{stdc_first_leading_one_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_first_leading_one_us}@(unsigned short value); +unsigned int @\libglobal{stdc_first_leading_one_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_first_leading_one_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_first_leading_one_ull}@(unsigned long long int value); +template @\seebelow@ stdc_first_leading_one(T value); + +unsigned int @\libglobal{stdc_first_trailing_zero_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_first_trailing_zero_us}@(unsigned short value); +unsigned int @\libglobal{stdc_first_trailing_zero_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_first_trailing_zero_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_first_trailing_zero_ull}@(unsigned long long int value); +template @\seebelow@ stdc_first_trailing_zero(T value); + +unsigned int @\libglobal{stdc_first_trailing_one_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_first_trailing_one_us}@(unsigned short value); +unsigned int @\libglobal{stdc_first_trailing_one_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_first_trailing_one_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_first_trailing_one_ull}@(unsigned long long int value); +template @\seebelow@ stdc_first_trailing_one(T value); + +unsigned int @\libglobal{stdc_count_zeros_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_count_zeros_us}@(unsigned short value); +unsigned int @\libglobal{stdc_count_zeros_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_count_zeros_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_count_zeros_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_count_zeros}@(T value); + +unsigned int @\libglobal{stdc_count_ones_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_count_ones_us}@(unsigned short value); +unsigned int @\libglobal{stdc_count_ones_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_count_ones_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_count_ones_ull}@(unsigned long long int value); +template @\seebelow@ stdc_count_ones(T value); + +bool @\libglobal{stdc_has_single_bit_uc}@(unsigned char value); +bool @\libglobal{stdc_has_single_bit_us}@(unsigned short value); +bool @\libglobal{stdc_has_single_bit_ui}@(unsigned int value); +bool @\libglobal{stdc_has_single_bit_ul}@(unsigned long int value); +bool @\libglobal{stdc_has_single_bit_ull}@(unsigned long long int value); +template bool @\libglobal{stdc_has_single_bit}@(T value); + +unsigned int @\libglobal{stdc_bit_width_uc}@(unsigned char value); +unsigned int @\libglobal{stdc_bit_width_us}@(unsigned short value); +unsigned int @\libglobal{stdc_bit_width_ui}@(unsigned int value); +unsigned int @\libglobal{stdc_bit_width_ul}@(unsigned long int value); +unsigned int @\libglobal{stdc_bit_width_ull}@(unsigned long long int value); +template @\seebelow@ @\libglobal{stdc_bit_width}@(T value); + +unsigned char @\libglobal{stdc_bit_floor_uc}@(unsigned char value); +unsigned short @\libglobal{stdc_bit_floor_us}@(unsigned short value); +unsigned int @\libglobal{stdc_bit_floor_ui}@(unsigned int value); +unsigned long int @\libglobal{stdc_bit_floor_ul}@(unsigned long int value); +unsigned long long int @\libglobal{stdc_bit_floor_ull}@(unsigned long long int value); +template T @\libglobal{stdc_bit_floor}@(T value); + +unsigned char @\libglobal{stdc_bit_ceil_uc}@(unsigned char value); +unsigned short @\libglobal{stdc_bit_ceil_us}@(unsigned short value); +unsigned int @\libglobal{stdc_bit_ceil_ui}@(unsigned int value); +unsigned long int @\libglobal{stdc_bit_ceil_ul}@(unsigned long int value); +unsigned long long int @\libglobal{stdc_bit_ceil_ull}@(unsigned long long int value); +template T @\libglobal{stdc_bit_ceil}@(T value); +\end{codeblock} + +\pnum +For a function template whose return type is not specified above, +the return type is +an \impldef{return types for \tcode{} functions} unsigned integer type +large enough to represent all possible result values. +Each function template has the same semantics +as the corresponding type-generic function with the same name +specified in \IsoCUndated{}:2024, 7.18. %% change to \xrefc{7.18} \pnum -\required -This function has no preconditions. +\mandates +\tcode{T} is an unsigned integer type. \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} +Otherwise, +the contents and meaning of the header \libheader{stdbit.h} are the same as +the C standard library header \tcode{}. -\end{itemdescr} +\xref{\IsoCUndated{}:2024, 7.18} %% TODO: change to \xrefc{7.18} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index cd814e0a13..45f98073b4 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -19,9 +19,387 @@ % % \removedxref{removed.label} +\movedxref{res.on.expects}{structure.specifications} +\removedxref{variant.traits} + +% [facets.examples] was removed. +\removedxref{facets.examples} + +% P0588 replaced function prototype scope with function parameter scope. +\movedxref{basic.scope.proto}{basic.scope.param} + +\movedxref{expr.pseudo}{expr.prim.id.dtor} + +\movedxref{utility.from.chars}{charconv.from.chars} +\movedxref{utility.to.chars}{charconv.to.chars} + +% [fs.definitions] and its contents were integrated into the main text. +% Note that ISO C++17 does not contain the [fs.def.*] subclauses. +\movedxrefs{fs.definitions}{% + \secref{fs.class.path}, + \secref{fs.conform.os}, + \secref{fs.general}, + \secref{fs.path.fmt.cvt}, + \secref{fs.path.generic}, + \secref{fs.race.behavior}} + +% Single-item array subclauses were dissolved. +\movedxref{array.size}{array.members} +\movedxref{array.data}{array.members} +\movedxref{array.fill}{array.members} +\movedxref{array.swap}{array.members} + +% Contents of [util.smartptr] was integrated into the parent. +\removedxref{util.smartptr} + +% Avoid duplication with synopsis. +\movedxref{re.regex.const}{re.regex} + +% Single-item [insert.iterators] subclauses were dissolved. +\movedxref{back.insert.iter.cons}{back.insert.iter.ops} +\movedxref{back.insert.iter.op=}{back.insert.iter.ops} +\movedxref{back.insert.iter.op*}{back.insert.iter.ops} +\movedxref{back.insert.iter.op++}{back.insert.iter.ops} + +\movedxref{front.insert.iter.cons}{front.insert.iter.ops} +\movedxref{front.insert.iter.op=}{front.insert.iter.ops} +\movedxref{front.insert.iter.op*}{front.insert.iter.ops} +\movedxref{front.insert.iter.op++}{front.insert.iter.ops} + +\movedxref{insert.iter.cons}{insert.iter.ops} +\movedxref{insert.iter.op=}{insert.iter.ops} +\movedxref{insert.iter.op*}{insert.iter.ops} +\movedxref{insert.iter.op++}{insert.iter.ops} + +% Single-item [reverse.iterators] subclauses were dissolved. +\movedxref{reverse.iter.op=}{reverse.iter.cons} + +\movedxref{reverse.iter.op==}{reverse.iter.cmp} +\movedxref{reverse.iter.op<}{reverse.iter.cmp} +\movedxref{reverse.iter.op!=}{reverse.iter.cmp} +\movedxref{reverse.iter.op>}{reverse.iter.cmp} +\movedxref{reverse.iter.op>=}{reverse.iter.cmp} +\movedxref{reverse.iter.op<=}{reverse.iter.cmp} + +\movedxref{reverse.iter.op.star}{reverse.iter.elem} +\movedxref{reverse.iter.opref}{reverse.iter.elem} +\movedxref{reverse.iter.opindex}{reverse.iter.elem} + +\movedxref{reverse.iter.op+}{reverse.iter.nav} +\movedxref{reverse.iter.op-}{reverse.iter.nav} +\movedxref{reverse.iter.op++}{reverse.iter.nav} +\movedxref{reverse.iter.op+=}{reverse.iter.nav} +\movedxref{reverse.iter.op--}{reverse.iter.nav} +\movedxref{reverse.iter.op-=}{reverse.iter.nav} + +\movedxref{reverse.iter.opdiff}{reverse.iter.nonmember} +\movedxref{reverse.iter.opsum}{reverse.iter.nonmember} +\movedxref{reverse.iter.make}{reverse.iter.nonmember} + +\removedxref{reverse.iter.ops} + +% Single-item [move.iterators] subclauses were dissolved. +\movedxref{move.iter.op=}{move.iter.cons} +\movedxref{move.iter.op.const}{move.iter.cons} + +\movedxref{move.iter.op.star}{move.iter.elem} +\movedxref{move.iter.op.ref}{move.iter.elem} +\movedxref{move.iter.op.index}{move.iter.elem} + +\movedxref{move.iter.op.+}{move.iter.nav} +\movedxref{move.iter.op.-}{move.iter.nav} +\movedxref{move.iter.op.incr}{move.iter.nav} +\movedxref{move.iter.op.+=}{move.iter.nav} +\movedxref{move.iter.op.decr}{move.iter.nav} +\movedxref{move.iter.op.-=}{move.iter.nav} + +\removedxref{move.iter.ops} + +% Individual swap sections were removed. +\removedxref{deque.special} +\removedxref{forwardlist.spec} +\removedxref{list.special} +\removedxref{vector.special} +\removedxref{map.special} +\removedxref{multimap.special} +\removedxref{set.special} +\removedxref{multiset.special} +\removedxref{unord.map.swap} +\removedxref{unord.multimap.swap} +\removedxref{unord.set.swap} +\removedxref{unord.multiset.swap} +\movedxref{re.regex.nmswap}{re.regex.nonmemb} + +% Deprecated features were removed. +\removedxref{depr.except.spec} +\removedxref{depr.cpp.headers} +\removedxref{depr.uncaught} +\removedxref{depr.func.adaptor.binding} +\removedxref{depr.weak.result_type} +\removedxref{depr.func.adaptor.typedefs} +\removedxref{depr.negators} +\removedxref{depr.default.allocator} +\removedxref{depr.storage.iterator} +\removedxref{depr.temporary.buffer} +\removedxref{depr.util.smartptr.shared.obs} + +% Deprecated headers were removed for some headers +\removedxref{depr.ccomplex.syn} +\removedxref{depr.cstdalign.syn} +\removedxref{depr.cstdbool.syn} +\removedxref{depr.ctgmath.syn} + +\movedxref{class.copy}{class.mem} + +% Top-level clause merging caused some Annex A subclauses to vanish. +\movedxref{gram.decl}{gram.dcl} +\movedxref{gram.derived}{gram.class} +\movedxref{gram.special}{gram.class} + +% Top-level clause merging caused some Annex C subclauses to vanish, too. +\movedxref{diff.conv}{diff.expr} +\movedxref{diff.decl}{diff.dcl} +\movedxref{diff.special}{diff.class} +\movedxref{diff.cpp03.conv}{diff.cpp03.expr} +\movedxref{diff.cpp03.dcl.decl}{diff.cpp03.dcl.dcl} +\movedxref{diff.cpp03.special}{diff.cpp03.class} +\movedxref{diff.cpp11.dcl.decl}{diff.cpp11.dcl.dcl} +\movedxref{diff.cpp14.decl}{diff.cpp14.dcl.dcl} +\movedxref{diff.cpp14.special}{diff.cpp14.class} + +% P1148R0 consolidated some Clause 20 subclauses. +\movedxref{string.rfind}{string.find} +\movedxref{string.find.first.of}{string.find} +\movedxref{string.find.last.of}{string.find} +\movedxref{string.find.first.not.of}{string.find} +\movedxref{string.find.last.not.of}{string.find} +\movedxref{string.op+=}{string.op.append} +\movedxref{string.op+}{string.op.plus} +\movedxref{string.operator==}{string.cmp} +\movedxref{string.op!=}{string.cmp} +\movedxref{string.op<}{string.cmp} +\movedxref{string.op>}{string.cmp} +\movedxref{string.op<=}{string.cmp} +\movedxref{string.op>=}{string.cmp} + +\movedxref{istream::sentry}{istream.sentry} +\movedxref{ostream::sentry}{ostream.sentry} +\movedxref{ios::failure}{ios.failure} +\movedxref{ios::fmtflags}{ios.fmtflags} +\movedxref{ios::iostate}{ios.iostate} +\movedxref{ios::openmode}{ios.openmode} +\movedxref{ios::seekdir}{ios.seekdir} +\movedxref{ios::Init}{ios.init} + +\removedxref{thread.decaycopy} + +\movedxref{iterator.container}{iterator.range} + +% Remove underscores in stable labels. +\movedxref{alg.all_of}{alg.all.of} +\movedxref{alg.any_of}{alg.any.of} +\movedxref{alg.is_permutation}{alg.is.permutation} +\movedxref{alg.none_of}{alg.none.of} +\movedxref{any.bad_any_cast}{any.bad.any.cast} +\movedxref{char.traits.specializations.char16_t}{char.traits.specializations.char16.t} +\movedxref{char.traits.specializations.char32_t}{char.traits.specializations.char32.t} +\movedxref{comparisons.equal_to}{comparisons.equal.to} +\movedxref{comparisons.greater_equal}{comparisons.greater.equal} +\movedxref{comparisons.less_equal}{comparisons.less.equal} +\movedxref{comparisons.not_equal_to}{comparisons.not.equal.to} +\movedxref{condition_variable.syn}{condition.variable.syn} +\movedxref{depr.static_constexpr}{depr.static.constexpr} +\movedxref{forward_list.syn}{forward.list.syn} +\movedxref{fs.class.directory_entry}{fs.class.directory.entry} +\movedxref{fs.class.directory_iterator}{fs.class.directory.iterator} +\movedxref{fs.class.file_status}{fs.class.file.status} +\movedxref{fs.class.filesystem_error}{fs.class.filesystem.error} +\movedxref{fs.enum.file_type}{fs.enum.file.type} +\movedxref{fs.file_status.cons}{fs.file.status.cons} +\movedxref{fs.file_status.mods}{fs.file.status.mods} +\movedxref{fs.file_status.obs}{fs.file.status.obs} +\movedxref{fs.filesystem_error.members}{fs.filesystem.error.members} +\movedxref{fs.op.copy_file}{fs.op.copy.file} +\movedxref{fs.op.copy_symlink}{fs.op.copy.symlink} +\movedxref{fs.op.create_directories}{fs.op.create.directories} +\movedxref{fs.op.create_directory}{fs.op.create.directory} +\movedxref{fs.op.create_dir_symlk}{fs.op.create.dir.symlk} +\movedxref{fs.op.create_hard_lk}{fs.op.create.hard.lk} +\movedxref{fs.op.create_symlink}{fs.op.create.symlink} +\movedxref{fs.op.current_path}{fs.op.current.path} +\movedxref{fs.op.file_size}{fs.op.file.size} +\movedxref{fs.op.hard_lk_ct}{fs.op.hard.lk.ct} +\movedxref{fs.op.is_block_file}{fs.op.is.block.file} +\movedxref{fs.op.is_char_file}{fs.op.is.char.file} +\movedxref{fs.op.is_directory}{fs.op.is.directory} +\movedxref{fs.op.is_empty}{fs.op.is.empty} +\movedxref{fs.op.is_fifo}{fs.op.is.fifo} +\movedxref{fs.op.is_other}{fs.op.is.other} +\movedxref{fs.op.is_regular_file}{fs.op.is.regular.file} +\movedxref{fs.op.is_socket}{fs.op.is.socket} +\movedxref{fs.op.is_symlink}{fs.op.is.symlink} +\movedxref{fs.op.last_write_time}{fs.op.last.write.time} +\movedxref{fs.op.read_symlink}{fs.op.read.symlink} +\movedxref{fs.op.remove_all}{fs.op.remove.all} +\movedxref{fs.op.resize_file}{fs.op.resize.file} +\movedxref{fs.op.status_known}{fs.op.status.known} +\movedxref{fs.op.symlink_status}{fs.op.symlink.status} +\movedxref{fs.op.temp_dir_path}{fs.op.temp.dir.path} +\movedxref{fs.op.weakly_canonical}{fs.op.weakly.canonical} +\movedxref{func.not_fn}{func.not.fn} +\movedxref{futures.future_error}{futures.future.error} +\movedxref{futures.shared_future}{futures.shared.future} +\movedxref{futures.unique_future}{futures.unique.future} +\movedxref{initializer_list.syn}{initializer.list.syn} +\movedxref{optional.comp_with_t}{optional.comp.with.t} +\movedxref{sf.cmath.assoc_laguerre}{sf.cmath.assoc.laguerre} +\movedxref{sf.cmath.assoc_legendre}{sf.cmath.assoc.legendre} +\movedxref{sf.cmath.comp_ellint_1}{sf.cmath.comp.ellint.1} +\movedxref{sf.cmath.comp_ellint_2}{sf.cmath.comp.ellint.2} +\movedxref{sf.cmath.comp_ellint_3}{sf.cmath.comp.ellint.3} +\movedxref{sf.cmath.cyl_bessel_i}{sf.cmath.cyl.bessel.i} +\movedxref{sf.cmath.cyl_bessel_j}{sf.cmath.cyl.bessel.j} +\movedxref{sf.cmath.cyl_bessel_k}{sf.cmath.cyl.bessel.k} +\movedxref{sf.cmath.cyl_neumann}{sf.cmath.cyl.neumann} +\movedxref{sf.cmath.ellint_1}{sf.cmath.ellint.1} +\movedxref{sf.cmath.ellint_2}{sf.cmath.ellint.2} +\movedxref{sf.cmath.ellint_3}{sf.cmath.ellint.3} +\movedxref{sf.cmath.riemann_zeta}{sf.cmath.riemann.zeta} +\movedxref{sf.cmath.sph_bessel}{sf.cmath.sph.bessel} +\movedxref{sf.cmath.sph_legendre}{sf.cmath.sph.legendre} +\movedxref{sf.cmath.sph_neumann}{sf.cmath.sph.neumann} +\movedxref{shared_mutex.syn}{shared.mutex.syn} +\movedxref{system_error.syn}{system.error.syn} +\movedxref{time.traits.duration_values}{time.traits.duration.values} +\movedxref{time.traits.is_fp}{time.traits.is.fp} +\movedxref{utility.as_const}{utility.as.const} + +% Dissolved subclause. +\movedxref{func.wrap.badcall.const}{func.wrap.badcall} + +% Shortened label +\movedxref{language.support}{support} + +% Other fixes +\removedxref{intro.ack} + +\movedxref{conversions}{locale.convenience} + +% CD and DIS C++20 +\removedxref{fs.norm.ref} +\movedxref{definitions}{intro.defs} +\removedxref{defns.arbitrary.stream} +\removedxref{defns.comparison} +\removedxref{defns.default.behavior.func} +\removedxref{defns.iostream.templates} +\removedxref{defns.repositional.stream} + +% Fix solitary subclauses +\movedxref{unreachable.sentinels}{unreachable.sentinel} +\movedxref{default.sentinels}{default.sentinel} +\movedxref{depr.iterator.primitives}{depr.iterator} +\movedxref{depr.iterator.basic}{depr.iterator} + +\movedxref{re.def}{intro.refs} +\movedxref{basic.scope.declarative}{basic.scope.scope} +\movedxref{basic.funscope}{stmt.label} +\movedxref{basic.scope.hiding}{basic.lookup} +\movedxref{basic.lookup.classref}{basic.lookup.qual} +\movedxref{namespace.memdef}{namespace.def} +\movedxref{class.this}{expr.prim.this} +\movedxref{class.mfct.non-static.general}{class.mfct.non.static} +\movedxref{class.nested.type}{diff.basic} +\movedxref{over.load}{basic.scope.scope} +\movedxref{over.dcl}{basic.link} +\movedxref{temp.nondep}{temp.res} +\movedxref{temp.inject}{temp.friend} + +% P2096R2 Generalized wording for partial specializations +\movedxref{temp.class.spec}{temp.spec.partial} +\movedxref{temp.class.spec.general}{temp.spec.partial.general} +\movedxref{temp.class.spec.match}{temp.spec.partial.match} +\movedxref{temp.class.order}{temp.spec.partial.order} +\movedxref{temp.class.spec.mfunc}{temp.spec.partial.member} + +\movedxref{forwardlist}{forward.list} +\movedxref{forwardlist.overview}{forward.list.overview} +\movedxref{forwardlist.cons}{forward.list.cons} +\movedxref{forwardlist.iter}{forward.list.iter} +\movedxref{forwardlist.access}{forward.list.access} +\movedxref{forwardlist.modifiers}{forward.list.modifiers} +\movedxref{forwardlist.ops}{forward.list.ops} + +% P2186R2 Removing Garbage Collection Support +\removedxref{basic.stc.dynamic.safety} +\removedxref{util.dynamic.safety} +\removedxref{res.on.pointer.storage} + +% LWG2818 "::std::" everywhere rule needs tweaking +\removedxref{fs.req.namespace} +\movedxref{fs.req.general}{fs.req} + +% P2325R3 Views should not be required to be default constructible +% P2494R2 Relaxing range adaptors to allow for move only types +% range.semi.wrap => range.copy.wrap => range.move.wrap +\movedxref{range.semi.wrap}{range.move.wrap} + +% P2210R2 Superior String Splitting +\movedxref{range.split.outer}{range.lazy.split.outer} +\movedxref{range.split.outer.value}{range.lazy.split.outer.value} +\movedxref{range.split.inner}{range.lazy.split.inner} + +% P2128R6 Multidimensional subscript operator +\removedxref{depr.comma.subscript} + +% P2340R1 Clarifying the status of the "C headers" +\movedxref{depr.c.headers}{support.c.headers} +\movedxref{depr.c.headers.general}{support.c.headers.general} +\movedxref{depr.c.headers.other}{support.c.headers.other} +\movedxref{depr.complex.h.syn}{complex.h.syn} +\movedxref{depr.iso646.h.syn}{iso646.h.syn} +\movedxref{depr.stdalign.h.syn}{stdalign.h.syn} +\movedxref{depr.stdbool.h.syn}{stdbool.h.syn} +\movedxref{depr.tgmath.h.syn}{tgmath.h.syn} + +\movedxref{istringstream.assign}{istringstream.swap} +\movedxref{ostringstream.assign}{ostringstream.swap} +\movedxref{stringstream.assign}{stringstream.swap} +\movedxref{ifstream.assign}{ifstream.swap} +\movedxref{ofstream.assign}{ofstream.swap} +\movedxref{fstream.assign}{fstream.swap} + +% P2387R3 Pipe support for user-defined range adaptors +\movedxref{func.bind.front}{func.bind.partial} + +\movedxref{class.mfct.non-static}{class.mfct.non.static} +\movedxref{defns.direct-non-list-init}{dcl.init.list} +\movedxref{defns.expression-equivalent}{defns.expression.equivalent} + +% P1467R9 Extended floating-point types and standard names +\movedxref{complex.special}{complex.members} +\movedxref{cstdint}{support.arith.types} +\removedxref{cstdint.general} + +% LWG3659 Consider ATOMIC_FLAG_INIT undeprecation +\removedxref{depr.atomics.flag} + +% LWG3818 Exposition-only concepts are not described in library intro +\movedxref{expos.only.func}{expos.only.entity} +\removedxref{expos.only.types} + +% P2614R2 Deprecate numeric_limits::has_denorm +\movedxref{denorm.style}{depr.numeric.limits.has.denorm} +\removedxref{fp.style} + +% CD and DIS C++2023 +\movedxref{defns.multibyte}{multibyte.strings} + % P2864R2 Remove deprecated arithmetic conversions \removedxref{depr.arith.conv.enum} +% P2866R5 Remove deprecated array comparisons +\removedxref{depr.array.comp} + % P2871R3 Remove deprecated header \removedxref{depr.codecvt.syn} \removedxref{depr.locale.stdcvt} @@ -68,6 +446,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: % @@ -79,13 +462,43 @@ % https://github.com/cplusplus/draft/pull/6255 \movedxref{container.gen.reqmts}{container.requirements.general} -% P2875 Undeprecate polymorphic_allocator::destroy +% P2875R4 Undeprecate polymorphic_allocator::destroy \movedxref{depr.mem.poly.allocator.mem}{mem.poly.allocator.mem} % https://github.com/cplusplus/draft/pull/6653 \movedxref{mismatch}{alg.mismatch} +% P2300R10 std::execution +\movedxref{stopsource.nonmembers}{stopsource} +\movedxref{stoptoken.cons}{stopsource} +\movedxref{stoptoken.nonmembers}{stopsource} + +% https://github.com/cplusplus/draft/pull/7276 +\movedxref{except.uncaught}{except.throw} + +% https://github.com/cplusplus/draft/pull/7345 +\movedxref{basic.stc.inherit}{basic.stc.general} + +% https://github.com/cplusplus/draft/pull/7524 +\movedxref{expr.ass}{expr.assign} +\movedxref{over.ass}{over.assign} + +% CWG 2024-11-20 in Wroclaw; https://github.com/cplusplus/draft/pull/7485 +\movedxref{stmt.stmt}{stmt} +\movedxref{dcl.dcl}{dcl} + +% P1494R5 added more to this section and expanded its scope +\movedxref{utility.unreachable}{utility.undefined} + %%% Deprecated features. %%% Example: % % \deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref) + +\removedxref{util.smartptr.shared.atomic} +\removedxref{res.on.required} +\deprxref{fs.path.factory} +\movedxref{operators}{depr.relops} + +% P3475R2 Defang and deprecate memory_order::consume +\removedxref{dcl.attr.depend} diff --git a/source/xrefprev b/source/xrefprev index 72e4f16ee5..65de28a389 100644 --- a/source/xrefprev +++ b/source/xrefprev @@ -1,3072 +1,2756 @@ -\glossaryentry{intro.scope@ {\memgloterm{intro.scope}}{\memglodesc{(\ref {intro.scope})}} {\memgloref{}}|memjustarg}{1} -\glossaryentry{intro.refs@ {\memgloterm{intro.refs}}{\memglodesc{(\ref {intro.refs})}} {\memgloref{}}|memjustarg}{2} -\glossaryentry{intro.defs@ {\memgloterm{intro.defs}}{\memglodesc{(\ref {intro.defs})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.access@ {\memgloterm{defns.access}}{\memglodesc{(\ref {defns.access})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.argument@ {\memgloterm{defns.argument}}{\memglodesc{(\ref {defns.argument})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.argument.macro@ {\memgloterm{defns.argument.macro}}{\memglodesc{(\ref {defns.argument.macro})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.argument.throw@ {\memgloterm{defns.argument.throw}}{\memglodesc{(\ref {defns.argument.throw})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.argument.templ@ {\memgloterm{defns.argument.templ}}{\memglodesc{(\ref {defns.argument.templ})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.block@ {\memgloterm{defns.block}}{\memglodesc{(\ref {defns.block})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.block.stmt@ {\memgloterm{defns.block.stmt}}{\memglodesc{(\ref {defns.block.stmt})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.character@ {\memgloterm{defns.character}}{\memglodesc{(\ref {defns.character})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.character.container@ {\memgloterm{defns.character.container}}{\memglodesc{(\ref {defns.character.container})}} {\memgloref{}}|memjustarg}{3} -\glossaryentry{defns.regex.collating.element@ {\memgloterm{defns.regex.collating.element}}{\memglodesc{(\ref {defns.regex.collating.element})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.component@ {\memgloterm{defns.component}}{\memglodesc{(\ref {defns.component})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.cond.supp@ {\memgloterm{defns.cond.supp}}{\memglodesc{(\ref {defns.cond.supp})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.const.subexpr@ {\memgloterm{defns.const.subexpr}}{\memglodesc{(\ref {defns.const.subexpr})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.deadlock@ {\memgloterm{defns.deadlock}}{\memglodesc{(\ref {defns.deadlock})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.default.behavior.impl@ {\memgloterm{defns.default.behavior.impl}}{\memglodesc{(\ref {defns.default.behavior.impl})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.diagnostic@ {\memgloterm{defns.diagnostic}}{\memglodesc{(\ref {defns.diagnostic})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.dynamic.type@ {\memgloterm{defns.dynamic.type}}{\memglodesc{(\ref {defns.dynamic.type})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.dynamic.type.prvalue@ {\memgloterm{defns.dynamic.type.prvalue}}{\memglodesc{(\ref {defns.dynamic.type.prvalue})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.expression.equivalent@ {\memgloterm{defns.expression.equivalent}}{\memglodesc{(\ref {defns.expression.equivalent})}} {\memgloref{}}|memjustarg}{4} -\glossaryentry{defns.regex.finite.state.machine@ {\memgloterm{defns.regex.finite.state.machine}}{\memglodesc{(\ref {defns.regex.finite.state.machine})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.regex.format.specifier@ {\memgloterm{defns.regex.format.specifier}}{\memglodesc{(\ref {defns.regex.format.specifier})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.handler@ {\memgloterm{defns.handler}}{\memglodesc{(\ref {defns.handler})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.ill.formed@ {\memgloterm{defns.ill.formed}}{\memglodesc{(\ref {defns.ill.formed})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.impl.defined@ {\memgloterm{defns.impl.defined}}{\memglodesc{(\ref {defns.impl.defined})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.order.ptr@ {\memgloterm{defns.order.ptr}}{\memglodesc{(\ref {defns.order.ptr})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.impl.limits@ {\memgloterm{defns.impl.limits}}{\memglodesc{(\ref {defns.impl.limits})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.locale.specific@ {\memgloterm{defns.locale.specific}}{\memglodesc{(\ref {defns.locale.specific})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.regex.matched@ {\memgloterm{defns.regex.matched}}{\memglodesc{(\ref {defns.regex.matched})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.modifier@ {\memgloterm{defns.modifier}}{\memglodesc{(\ref {defns.modifier})}} {\memgloref{}}|memjustarg}{5} -\glossaryentry{defns.move.assign@ {\memgloterm{defns.move.assign}}{\memglodesc{(\ref {defns.move.assign})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.move.constr@ {\memgloterm{defns.move.constr}}{\memglodesc{(\ref {defns.move.constr})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.nonconst.libcall@ {\memgloterm{defns.nonconst.libcall}}{\memglodesc{(\ref {defns.nonconst.libcall})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.ntcts@ {\memgloterm{defns.ntcts}}{\memglodesc{(\ref {defns.ntcts})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.observer@ {\memgloterm{defns.observer}}{\memglodesc{(\ref {defns.observer})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.parameter@ {\memgloterm{defns.parameter}}{\memglodesc{(\ref {defns.parameter})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.parameter.macro@ {\memgloterm{defns.parameter.macro}}{\memglodesc{(\ref {defns.parameter.macro})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.parameter.templ@ {\memgloterm{defns.parameter.templ}}{\memglodesc{(\ref {defns.parameter.templ})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.regex.primary.equivalence.class@ {\memgloterm{defns.regex.primary.equivalence.class}}{\memglodesc{(\ref {defns.regex.primary.equivalence.class})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.prog.def.spec@ {\memgloterm{defns.prog.def.spec}}{\memglodesc{(\ref {defns.prog.def.spec})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.prog.def.type@ {\memgloterm{defns.prog.def.type}}{\memglodesc{(\ref {defns.prog.def.type})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.projection@ {\memgloterm{defns.projection}}{\memglodesc{(\ref {defns.projection})}} {\memgloref{}}|memjustarg}{6} -\glossaryentry{defns.referenceable@ {\memgloterm{defns.referenceable}}{\memglodesc{(\ref {defns.referenceable})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.regex.regular.expression@ {\memgloterm{defns.regex.regular.expression}}{\memglodesc{(\ref {defns.regex.regular.expression})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.replacement@ {\memgloterm{defns.replacement}}{\memglodesc{(\ref {defns.replacement})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.required.behavior@ {\memgloterm{defns.required.behavior}}{\memglodesc{(\ref {defns.required.behavior})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.reserved.function@ {\memgloterm{defns.reserved.function}}{\memglodesc{(\ref {defns.reserved.function})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.signature@ {\memgloterm{defns.signature}}{\memglodesc{(\ref {defns.signature})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.signature.friend@ {\memgloterm{defns.signature.friend}}{\memglodesc{(\ref {defns.signature.friend})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.signature.templ@ {\memgloterm{defns.signature.templ}}{\memglodesc{(\ref {defns.signature.templ})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.signature.templ.friend@ {\memgloterm{defns.signature.templ.friend}}{\memglodesc{(\ref {defns.signature.templ.friend})}} {\memgloref{}}|memjustarg}{7} -\glossaryentry{defns.signature.spec@ {\memgloterm{defns.signature.spec}}{\memglodesc{(\ref {defns.signature.spec})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.signature.member@ {\memgloterm{defns.signature.member}}{\memglodesc{(\ref {defns.signature.member})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.signature.member.templ@ {\memgloterm{defns.signature.member.templ}}{\memglodesc{(\ref {defns.signature.member.templ})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.signature.member.spec@ {\memgloterm{defns.signature.member.spec}}{\memglodesc{(\ref {defns.signature.member.spec})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.signature.template.head@ {\memgloterm{defns.signature.template.head}}{\memglodesc{(\ref {defns.signature.template.head})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.stable@ {\memgloterm{defns.stable}}{\memglodesc{(\ref {defns.stable})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.static.type@ {\memgloterm{defns.static.type}}{\memglodesc{(\ref {defns.static.type})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.regex.subexpression@ {\memgloterm{defns.regex.subexpression}}{\memglodesc{(\ref {defns.regex.subexpression})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.traits@ {\memgloterm{defns.traits}}{\memglodesc{(\ref {defns.traits})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.unblock@ {\memgloterm{defns.unblock}}{\memglodesc{(\ref {defns.unblock})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.undefined@ {\memgloterm{defns.undefined}}{\memglodesc{(\ref {defns.undefined})}} {\memgloref{}}|memjustarg}{8} -\glossaryentry{defns.unspecified@ {\memgloterm{defns.unspecified}}{\memglodesc{(\ref {defns.unspecified})}} {\memgloref{}}|memjustarg}{9} -\glossaryentry{defns.valid@ {\memgloterm{defns.valid}}{\memglodesc{(\ref {defns.valid})}} {\memgloref{}}|memjustarg}{9} -\glossaryentry{defns.well.formed@ {\memgloterm{defns.well.formed}}{\memglodesc{(\ref {defns.well.formed})}} {\memgloref{}}|memjustarg}{9} -\glossaryentry{intro@ {\memgloterm{intro}}{\memglodesc{(\ref {intro})}} {\memgloref{}}|memjustarg}{10} -\glossaryentry{intro.compliance@ {\memgloterm{intro.compliance}}{\memglodesc{(\ref {intro.compliance})}} {\memgloref{}}|memjustarg}{10} -\glossaryentry{intro.compliance.general@ {\memgloterm{intro.compliance.general}}{\memglodesc{(\ref {intro.compliance.general})}} {\memgloref{}}|memjustarg}{10} -\glossaryentry{intro.abstract@ {\memgloterm{intro.abstract}}{\memglodesc{(\ref {intro.abstract})}} {\memgloref{}}|memjustarg}{11} -\glossaryentry{intro.structure@ {\memgloterm{intro.structure}}{\memglodesc{(\ref {intro.structure})}} {\memgloref{}}|memjustarg}{11} -\glossaryentry{syntax@ {\memgloterm{syntax}}{\memglodesc{(\ref {syntax})}} {\memgloref{}}|memjustarg}{12} -\glossaryentry{lex@ {\memgloterm{lex}}{\memglodesc{(\ref {lex})}} {\memgloref{}}|memjustarg}{13} -\glossaryentry{lex.separate@ {\memgloterm{lex.separate}}{\memglodesc{(\ref {lex.separate})}} {\memgloref{}}|memjustarg}{13} -\glossaryentry{lex.phases@ {\memgloterm{lex.phases}}{\memglodesc{(\ref {lex.phases})}} {\memgloref{}}|memjustarg}{13} -\glossaryentry{lex.charset@ {\memgloterm{lex.charset}}{\memglodesc{(\ref {lex.charset})}} {\memgloref{}}|memjustarg}{14} -\glossaryentry{lex.pptoken@ {\memgloterm{lex.pptoken}}{\memglodesc{(\ref {lex.pptoken})}} {\memgloref{}}|memjustarg}{17} -\glossaryentry{lex.digraph@ {\memgloterm{lex.digraph}}{\memglodesc{(\ref {lex.digraph})}} {\memgloref{}}|memjustarg}{18} -\glossaryentry{lex.token@ {\memgloterm{lex.token}}{\memglodesc{(\ref {lex.token})}} {\memgloref{}}|memjustarg}{18} -\glossaryentry{lex.comment@ {\memgloterm{lex.comment}}{\memglodesc{(\ref {lex.comment})}} {\memgloref{}}|memjustarg}{18} -\glossaryentry{lex.header@ {\memgloterm{lex.header}}{\memglodesc{(\ref {lex.header})}} {\memgloref{}}|memjustarg}{18} -\glossaryentry{lex.ppnumber@ {\memgloterm{lex.ppnumber}}{\memglodesc{(\ref {lex.ppnumber})}} {\memgloref{}}|memjustarg}{19} -\glossaryentry{lex.name@ {\memgloterm{lex.name}}{\memglodesc{(\ref {lex.name})}} {\memgloref{}}|memjustarg}{19} -\glossaryentry{lex.key@ {\memgloterm{lex.key}}{\memglodesc{(\ref {lex.key})}} {\memgloref{}}|memjustarg}{20} -\glossaryentry{lex.operators@ {\memgloterm{lex.operators}}{\memglodesc{(\ref {lex.operators})}} {\memgloref{}}|memjustarg}{20} -\glossaryentry{lex.literal@ {\memgloterm{lex.literal}}{\memglodesc{(\ref {lex.literal})}} {\memgloref{}}|memjustarg}{21} -\glossaryentry{lex.literal.kinds@ {\memgloterm{lex.literal.kinds}}{\memglodesc{(\ref {lex.literal.kinds})}} {\memgloref{}}|memjustarg}{21} -\glossaryentry{lex.icon@ {\memgloterm{lex.icon}}{\memglodesc{(\ref {lex.icon})}} {\memgloref{}}|memjustarg}{21} -\glossaryentry{lex.ccon@ {\memgloterm{lex.ccon}}{\memglodesc{(\ref {lex.ccon})}} {\memgloref{}}|memjustarg}{23} -\glossaryentry{lex.fcon@ {\memgloterm{lex.fcon}}{\memglodesc{(\ref {lex.fcon})}} {\memgloref{}}|memjustarg}{25} -\glossaryentry{lex.string@ {\memgloterm{lex.string}}{\memglodesc{(\ref {lex.string})}} {\memgloref{}}|memjustarg}{26} -\glossaryentry{lex.bool@ {\memgloterm{lex.bool}}{\memglodesc{(\ref {lex.bool})}} {\memgloref{}}|memjustarg}{29} -\glossaryentry{lex.nullptr@ {\memgloterm{lex.nullptr}}{\memglodesc{(\ref {lex.nullptr})}} {\memgloref{}}|memjustarg}{29} -\glossaryentry{lex.ext@ {\memgloterm{lex.ext}}{\memglodesc{(\ref {lex.ext})}} {\memgloref{}}|memjustarg}{29} -\glossaryentry{basic@ {\memgloterm{basic}}{\memglodesc{(\ref {basic})}} {\memgloref{}}|memjustarg}{32} -\glossaryentry{basic.pre@ {\memgloterm{basic.pre}}{\memglodesc{(\ref {basic.pre})}} {\memgloref{}}|memjustarg}{32} -\glossaryentry{basic.def@ {\memgloterm{basic.def}}{\memglodesc{(\ref {basic.def})}} {\memgloref{}}|memjustarg}{33} -\glossaryentry{basic.def.odr@ {\memgloterm{basic.def.odr}}{\memglodesc{(\ref {basic.def.odr})}} {\memgloref{}}|memjustarg}{34} -\glossaryentry{basic.scope@ {\memgloterm{basic.scope}}{\memglodesc{(\ref {basic.scope})}} {\memgloref{}}|memjustarg}{39} -\glossaryentry{basic.scope.scope@ {\memgloterm{basic.scope.scope}}{\memglodesc{(\ref {basic.scope.scope})}} {\memgloref{}}|memjustarg}{39} -\glossaryentry{basic.scope.pdecl@ {\memgloterm{basic.scope.pdecl}}{\memglodesc{(\ref {basic.scope.pdecl})}} {\memgloref{}}|memjustarg}{41} -\glossaryentry{basic.scope.block@ {\memgloterm{basic.scope.block}}{\memglodesc{(\ref {basic.scope.block})}} {\memgloref{}}|memjustarg}{42} -\glossaryentry{basic.scope.param@ {\memgloterm{basic.scope.param}}{\memglodesc{(\ref {basic.scope.param})}} {\memgloref{}}|memjustarg}{43} -\glossaryentry{basic.scope.lambda@ {\memgloterm{basic.scope.lambda}}{\memglodesc{(\ref {basic.scope.lambda})}} {\memgloref{}}|memjustarg}{43} -\glossaryentry{basic.scope.namespace@ {\memgloterm{basic.scope.namespace}}{\memglodesc{(\ref {basic.scope.namespace})}} {\memgloref{}}|memjustarg}{43} -\glossaryentry{basic.scope.class@ {\memgloterm{basic.scope.class}}{\memglodesc{(\ref {basic.scope.class})}} {\memgloref{}}|memjustarg}{44} -\glossaryentry{basic.scope.enum@ {\memgloterm{basic.scope.enum}}{\memglodesc{(\ref {basic.scope.enum})}} {\memgloref{}}|memjustarg}{44} -\glossaryentry{basic.scope.temp@ {\memgloterm{basic.scope.temp}}{\memglodesc{(\ref {basic.scope.temp})}} {\memgloref{}}|memjustarg}{44} -\glossaryentry{basic.lookup@ {\memgloterm{basic.lookup}}{\memglodesc{(\ref {basic.lookup})}} {\memgloref{}}|memjustarg}{44} -\glossaryentry{basic.lookup.general@ {\memgloterm{basic.lookup.general}}{\memglodesc{(\ref {basic.lookup.general})}} {\memgloref{}}|memjustarg}{44} -\glossaryentry{class.member.lookup@ {\memgloterm{class.member.lookup}}{\memglodesc{(\ref {class.member.lookup})}} {\memgloref{}}|memjustarg}{45} -\glossaryentry{basic.lookup.unqual@ {\memgloterm{basic.lookup.unqual}}{\memglodesc{(\ref {basic.lookup.unqual})}} {\memgloref{}}|memjustarg}{48} -\glossaryentry{basic.lookup.argdep@ {\memgloterm{basic.lookup.argdep}}{\memglodesc{(\ref {basic.lookup.argdep})}} {\memgloref{}}|memjustarg}{49} -\glossaryentry{basic.lookup.qual@ {\memgloterm{basic.lookup.qual}}{\memglodesc{(\ref {basic.lookup.qual})}} {\memgloref{}}|memjustarg}{52} -\glossaryentry{basic.lookup.qual.general@ {\memgloterm{basic.lookup.qual.general}}{\memglodesc{(\ref {basic.lookup.qual.general})}} {\memgloref{}}|memjustarg}{52} -\glossaryentry{class.qual@ {\memgloterm{class.qual}}{\memglodesc{(\ref {class.qual})}} {\memgloref{}}|memjustarg}{54} -\glossaryentry{namespace.qual@ {\memgloterm{namespace.qual}}{\memglodesc{(\ref {namespace.qual})}} {\memgloref{}}|memjustarg}{54} -\glossaryentry{basic.lookup.elab@ {\memgloterm{basic.lookup.elab}}{\memglodesc{(\ref {basic.lookup.elab})}} {\memgloref{}}|memjustarg}{56} -\glossaryentry{basic.lookup.udir@ {\memgloterm{basic.lookup.udir}}{\memglodesc{(\ref {basic.lookup.udir})}} {\memgloref{}}|memjustarg}{57} -\glossaryentry{basic.link@ {\memgloterm{basic.link}}{\memglodesc{(\ref {basic.link})}} {\memgloref{}}|memjustarg}{57} -\glossaryentry{basic.memobj@ {\memgloterm{basic.memobj}}{\memglodesc{(\ref {basic.memobj})}} {\memgloref{}}|memjustarg}{61} -\glossaryentry{intro.memory@ {\memgloterm{intro.memory}}{\memglodesc{(\ref {intro.memory})}} {\memgloref{}}|memjustarg}{61} -\glossaryentry{intro.object@ {\memgloterm{intro.object}}{\memglodesc{(\ref {intro.object})}} {\memgloref{}}|memjustarg}{62} -\glossaryentry{basic.life@ {\memgloterm{basic.life}}{\memglodesc{(\ref {basic.life})}} {\memgloref{}}|memjustarg}{64} -\glossaryentry{basic.indet@ {\memgloterm{basic.indet}}{\memglodesc{(\ref {basic.indet})}} {\memgloref{}}|memjustarg}{67} -\glossaryentry{basic.stc@ {\memgloterm{basic.stc}}{\memglodesc{(\ref {basic.stc})}} {\memgloref{}}|memjustarg}{67} -\glossaryentry{basic.stc.general@ {\memgloterm{basic.stc.general}}{\memglodesc{(\ref {basic.stc.general})}} {\memgloref{}}|memjustarg}{67} -\glossaryentry{basic.stc.static@ {\memgloterm{basic.stc.static}}{\memglodesc{(\ref {basic.stc.static})}} {\memgloref{}}|memjustarg}{68} -\glossaryentry{basic.stc.thread@ {\memgloterm{basic.stc.thread}}{\memglodesc{(\ref {basic.stc.thread})}} {\memgloref{}}|memjustarg}{68} -\glossaryentry{basic.stc.auto@ {\memgloterm{basic.stc.auto}}{\memglodesc{(\ref {basic.stc.auto})}} {\memgloref{}}|memjustarg}{68} -\glossaryentry{basic.stc.dynamic@ {\memgloterm{basic.stc.dynamic}}{\memglodesc{(\ref {basic.stc.dynamic})}} {\memgloref{}}|memjustarg}{68} -\glossaryentry{basic.stc.dynamic.general@ {\memgloterm{basic.stc.dynamic.general}}{\memglodesc{(\ref {basic.stc.dynamic.general})}} {\memgloref{}}|memjustarg}{68} -\glossaryentry{basic.stc.dynamic.allocation@ {\memgloterm{basic.stc.dynamic.allocation}}{\memglodesc{(\ref {basic.stc.dynamic.allocation})}} {\memgloref{}}|memjustarg}{69} -\glossaryentry{basic.stc.dynamic.deallocation@ {\memgloterm{basic.stc.dynamic.deallocation}}{\memglodesc{(\ref {basic.stc.dynamic.deallocation})}} {\memgloref{}}|memjustarg}{70} -\glossaryentry{basic.stc.inherit@ {\memgloterm{basic.stc.inherit}}{\memglodesc{(\ref {basic.stc.inherit})}} {\memgloref{}}|memjustarg}{70} -\glossaryentry{basic.align@ {\memgloterm{basic.align}}{\memglodesc{(\ref {basic.align})}} {\memgloref{}}|memjustarg}{70} -\glossaryentry{class.temporary@ {\memgloterm{class.temporary}}{\memglodesc{(\ref {class.temporary})}} {\memgloref{}}|memjustarg}{71} -\glossaryentry{basic.types@ {\memgloterm{basic.types}}{\memglodesc{(\ref {basic.types})}} {\memgloref{}}|memjustarg}{74} -\glossaryentry{basic.types.general@ {\memgloterm{basic.types.general}}{\memglodesc{(\ref {basic.types.general})}} {\memgloref{}}|memjustarg}{74} -\glossaryentry{basic.fundamental@ {\memgloterm{basic.fundamental}}{\memglodesc{(\ref {basic.fundamental})}} {\memgloref{}}|memjustarg}{76} -\glossaryentry{basic.extended.fp@ {\memgloterm{basic.extended.fp}}{\memglodesc{(\ref {basic.extended.fp})}} {\memgloref{}}|memjustarg}{78} -\glossaryentry{basic.compound@ {\memgloterm{basic.compound}}{\memglodesc{(\ref {basic.compound})}} {\memgloref{}}|memjustarg}{79} -\glossaryentry{basic.type.qualifier@ {\memgloterm{basic.type.qualifier}}{\memglodesc{(\ref {basic.type.qualifier})}} {\memgloref{}}|memjustarg}{80} -\glossaryentry{conv.rank@ {\memgloterm{conv.rank}}{\memglodesc{(\ref {conv.rank})}} {\memgloref{}}|memjustarg}{81} -\glossaryentry{basic.exec@ {\memgloterm{basic.exec}}{\memglodesc{(\ref {basic.exec})}} {\memgloref{}}|memjustarg}{82} -\glossaryentry{intro.execution@ {\memgloterm{intro.execution}}{\memglodesc{(\ref {intro.execution})}} {\memgloref{}}|memjustarg}{82} -\glossaryentry{intro.multithread@ {\memgloterm{intro.multithread}}{\memglodesc{(\ref {intro.multithread})}} {\memgloref{}}|memjustarg}{85} -\glossaryentry{intro.multithread.general@ {\memgloterm{intro.multithread.general}}{\memglodesc{(\ref {intro.multithread.general})}} {\memgloref{}}|memjustarg}{85} -\glossaryentry{intro.races@ {\memgloterm{intro.races}}{\memglodesc{(\ref {intro.races})}} {\memgloref{}}|memjustarg}{85} -\glossaryentry{intro.progress@ {\memgloterm{intro.progress}}{\memglodesc{(\ref {intro.progress})}} {\memgloref{}}|memjustarg}{88} -\glossaryentry{basic.start@ {\memgloterm{basic.start}}{\memglodesc{(\ref {basic.start})}} {\memgloref{}}|memjustarg}{90} -\glossaryentry{basic.start.main@ {\memgloterm{basic.start.main}}{\memglodesc{(\ref {basic.start.main})}} {\memgloref{}}|memjustarg}{90} -\glossaryentry{basic.start.static@ {\memgloterm{basic.start.static}}{\memglodesc{(\ref {basic.start.static})}} {\memgloref{}}|memjustarg}{91} -\glossaryentry{basic.start.dynamic@ {\memgloterm{basic.start.dynamic}}{\memglodesc{(\ref {basic.start.dynamic})}} {\memgloref{}}|memjustarg}{91} -\glossaryentry{basic.start.term@ {\memgloterm{basic.start.term}}{\memglodesc{(\ref {basic.start.term})}} {\memgloref{}}|memjustarg}{93} -\glossaryentry{expr@ {\memgloterm{expr}}{\memglodesc{(\ref {expr})}} {\memgloref{}}|memjustarg}{94} -\glossaryentry{expr.pre@ {\memgloterm{expr.pre}}{\memglodesc{(\ref {expr.pre})}} {\memgloref{}}|memjustarg}{94} -\glossaryentry{expr.prop@ {\memgloterm{expr.prop}}{\memglodesc{(\ref {expr.prop})}} {\memgloref{}}|memjustarg}{95} -\glossaryentry{basic.lval@ {\memgloterm{basic.lval}}{\memglodesc{(\ref {basic.lval})}} {\memgloref{}}|memjustarg}{95} -\glossaryentry{expr.type@ {\memgloterm{expr.type}}{\memglodesc{(\ref {expr.type})}} {\memgloref{}}|memjustarg}{96} -\glossaryentry{expr.context@ {\memgloterm{expr.context}}{\memglodesc{(\ref {expr.context})}} {\memgloref{}}|memjustarg}{97} -\glossaryentry{conv@ {\memgloterm{conv}}{\memglodesc{(\ref {conv})}} {\memgloref{}}|memjustarg}{98} -\glossaryentry{conv.general@ {\memgloterm{conv.general}}{\memglodesc{(\ref {conv.general})}} {\memgloref{}}|memjustarg}{98} -\glossaryentry{conv.lval@ {\memgloterm{conv.lval}}{\memglodesc{(\ref {conv.lval})}} {\memgloref{}}|memjustarg}{99} -\glossaryentry{conv.array@ {\memgloterm{conv.array}}{\memglodesc{(\ref {conv.array})}} {\memgloref{}}|memjustarg}{99} -\glossaryentry{conv.func@ {\memgloterm{conv.func}}{\memglodesc{(\ref {conv.func})}} {\memgloref{}}|memjustarg}{99} -\glossaryentry{conv.rval@ {\memgloterm{conv.rval}}{\memglodesc{(\ref {conv.rval})}} {\memgloref{}}|memjustarg}{99} -\glossaryentry{conv.qual@ {\memgloterm{conv.qual}}{\memglodesc{(\ref {conv.qual})}} {\memgloref{}}|memjustarg}{100} -\glossaryentry{conv.prom@ {\memgloterm{conv.prom}}{\memglodesc{(\ref {conv.prom})}} {\memgloref{}}|memjustarg}{100} -\glossaryentry{conv.fpprom@ {\memgloterm{conv.fpprom}}{\memglodesc{(\ref {conv.fpprom})}} {\memgloref{}}|memjustarg}{101} -\glossaryentry{conv.integral@ {\memgloterm{conv.integral}}{\memglodesc{(\ref {conv.integral})}} {\memgloref{}}|memjustarg}{101} -\glossaryentry{conv.double@ {\memgloterm{conv.double}}{\memglodesc{(\ref {conv.double})}} {\memgloref{}}|memjustarg}{101} -\glossaryentry{conv.fpint@ {\memgloterm{conv.fpint}}{\memglodesc{(\ref {conv.fpint})}} {\memgloref{}}|memjustarg}{101} -\glossaryentry{conv.ptr@ {\memgloterm{conv.ptr}}{\memglodesc{(\ref {conv.ptr})}} {\memgloref{}}|memjustarg}{102} -\glossaryentry{conv.mem@ {\memgloterm{conv.mem}}{\memglodesc{(\ref {conv.mem})}} {\memgloref{}}|memjustarg}{102} -\glossaryentry{conv.fctptr@ {\memgloterm{conv.fctptr}}{\memglodesc{(\ref {conv.fctptr})}} {\memgloref{}}|memjustarg}{102} -\glossaryentry{conv.bool@ {\memgloterm{conv.bool}}{\memglodesc{(\ref {conv.bool})}} {\memgloref{}}|memjustarg}{103} -\glossaryentry{expr.arith.conv@ {\memgloterm{expr.arith.conv}}{\memglodesc{(\ref {expr.arith.conv})}} {\memgloref{}}|memjustarg}{103} -\glossaryentry{expr.prim@ {\memgloterm{expr.prim}}{\memglodesc{(\ref {expr.prim})}} {\memgloref{}}|memjustarg}{103} -\glossaryentry{expr.prim.literal@ {\memgloterm{expr.prim.literal}}{\memglodesc{(\ref {expr.prim.literal})}} {\memgloref{}}|memjustarg}{103} -\glossaryentry{expr.prim.this@ {\memgloterm{expr.prim.this}}{\memglodesc{(\ref {expr.prim.this})}} {\memgloref{}}|memjustarg}{104} -\glossaryentry{expr.prim.paren@ {\memgloterm{expr.prim.paren}}{\memglodesc{(\ref {expr.prim.paren})}} {\memgloref{}}|memjustarg}{104} -\glossaryentry{expr.prim.id@ {\memgloterm{expr.prim.id}}{\memglodesc{(\ref {expr.prim.id})}} {\memgloref{}}|memjustarg}{104} -\glossaryentry{expr.prim.id.general@ {\memgloterm{expr.prim.id.general}}{\memglodesc{(\ref {expr.prim.id.general})}} {\memgloref{}}|memjustarg}{104} -\glossaryentry{expr.prim.id.unqual@ {\memgloterm{expr.prim.id.unqual}}{\memglodesc{(\ref {expr.prim.id.unqual})}} {\memgloref{}}|memjustarg}{105} -\glossaryentry{expr.prim.id.qual@ {\memgloterm{expr.prim.id.qual}}{\memglodesc{(\ref {expr.prim.id.qual})}} {\memgloref{}}|memjustarg}{107} -\glossaryentry{expr.prim.id.dtor@ {\memgloterm{expr.prim.id.dtor}}{\memglodesc{(\ref {expr.prim.id.dtor})}} {\memgloref{}}|memjustarg}{108} -\glossaryentry{expr.prim.lambda@ {\memgloterm{expr.prim.lambda}}{\memglodesc{(\ref {expr.prim.lambda})}} {\memgloref{}}|memjustarg}{108} -\glossaryentry{expr.prim.lambda.general@ {\memgloterm{expr.prim.lambda.general}}{\memglodesc{(\ref {expr.prim.lambda.general})}} {\memgloref{}}|memjustarg}{108} -\glossaryentry{expr.prim.lambda.closure@ {\memgloterm{expr.prim.lambda.closure}}{\memglodesc{(\ref {expr.prim.lambda.closure})}} {\memgloref{}}|memjustarg}{109} -\glossaryentry{expr.prim.lambda.capture@ {\memgloterm{expr.prim.lambda.capture}}{\memglodesc{(\ref {expr.prim.lambda.capture})}} {\memgloref{}}|memjustarg}{113} -\glossaryentry{expr.prim.fold@ {\memgloterm{expr.prim.fold}}{\memglodesc{(\ref {expr.prim.fold})}} {\memgloref{}}|memjustarg}{118} -\glossaryentry{expr.prim.req@ {\memgloterm{expr.prim.req}}{\memglodesc{(\ref {expr.prim.req})}} {\memgloref{}}|memjustarg}{119} -\glossaryentry{expr.prim.req.general@ {\memgloterm{expr.prim.req.general}}{\memglodesc{(\ref {expr.prim.req.general})}} {\memgloref{}}|memjustarg}{119} -\glossaryentry{expr.prim.req.simple@ {\memgloterm{expr.prim.req.simple}}{\memglodesc{(\ref {expr.prim.req.simple})}} {\memgloref{}}|memjustarg}{120} -\glossaryentry{expr.prim.req.type@ {\memgloterm{expr.prim.req.type}}{\memglodesc{(\ref {expr.prim.req.type})}} {\memgloref{}}|memjustarg}{120} -\glossaryentry{expr.prim.req.compound@ {\memgloterm{expr.prim.req.compound}}{\memglodesc{(\ref {expr.prim.req.compound})}} {\memgloref{}}|memjustarg}{120} -\glossaryentry{expr.prim.req.nested@ {\memgloterm{expr.prim.req.nested}}{\memglodesc{(\ref {expr.prim.req.nested})}} {\memgloref{}}|memjustarg}{121} -\glossaryentry{expr.compound@ {\memgloterm{expr.compound}}{\memglodesc{(\ref {expr.compound})}} {\memgloref{}}|memjustarg}{122} -\glossaryentry{expr.post@ {\memgloterm{expr.post}}{\memglodesc{(\ref {expr.post})}} {\memgloref{}}|memjustarg}{122} -\glossaryentry{expr.post.general@ {\memgloterm{expr.post.general}}{\memglodesc{(\ref {expr.post.general})}} {\memgloref{}}|memjustarg}{122} -\glossaryentry{expr.sub@ {\memgloterm{expr.sub}}{\memglodesc{(\ref {expr.sub})}} {\memgloref{}}|memjustarg}{122} -\glossaryentry{expr.call@ {\memgloterm{expr.call}}{\memglodesc{(\ref {expr.call})}} {\memgloref{}}|memjustarg}{122} -\glossaryentry{expr.type.conv@ {\memgloterm{expr.type.conv}}{\memglodesc{(\ref {expr.type.conv})}} {\memgloref{}}|memjustarg}{124} -\glossaryentry{expr.ref@ {\memgloterm{expr.ref}}{\memglodesc{(\ref {expr.ref})}} {\memgloref{}}|memjustarg}{125} -\glossaryentry{expr.post.incr@ {\memgloterm{expr.post.incr}}{\memglodesc{(\ref {expr.post.incr})}} {\memgloref{}}|memjustarg}{126} -\glossaryentry{expr.dynamic.cast@ {\memgloterm{expr.dynamic.cast}}{\memglodesc{(\ref {expr.dynamic.cast})}} {\memgloref{}}|memjustarg}{126} -\glossaryentry{expr.typeid@ {\memgloterm{expr.typeid}}{\memglodesc{(\ref {expr.typeid})}} {\memgloref{}}|memjustarg}{127} -\glossaryentry{expr.static.cast@ {\memgloterm{expr.static.cast}}{\memglodesc{(\ref {expr.static.cast})}} {\memgloref{}}|memjustarg}{128} -\glossaryentry{expr.reinterpret.cast@ {\memgloterm{expr.reinterpret.cast}}{\memglodesc{(\ref {expr.reinterpret.cast})}} {\memgloref{}}|memjustarg}{130} -\glossaryentry{expr.const.cast@ {\memgloterm{expr.const.cast}}{\memglodesc{(\ref {expr.const.cast})}} {\memgloref{}}|memjustarg}{131} -\glossaryentry{expr.unary@ {\memgloterm{expr.unary}}{\memglodesc{(\ref {expr.unary})}} {\memgloref{}}|memjustarg}{132} -\glossaryentry{expr.unary.general@ {\memgloterm{expr.unary.general}}{\memglodesc{(\ref {expr.unary.general})}} {\memgloref{}}|memjustarg}{132} -\glossaryentry{expr.unary.op@ {\memgloterm{expr.unary.op}}{\memglodesc{(\ref {expr.unary.op})}} {\memgloref{}}|memjustarg}{133} -\glossaryentry{expr.pre.incr@ {\memgloterm{expr.pre.incr}}{\memglodesc{(\ref {expr.pre.incr})}} {\memgloref{}}|memjustarg}{134} -\glossaryentry{expr.await@ {\memgloterm{expr.await}}{\memglodesc{(\ref {expr.await})}} {\memgloref{}}|memjustarg}{134} -\glossaryentry{expr.sizeof@ {\memgloterm{expr.sizeof}}{\memglodesc{(\ref {expr.sizeof})}} {\memgloref{}}|memjustarg}{136} -\glossaryentry{expr.alignof@ {\memgloterm{expr.alignof}}{\memglodesc{(\ref {expr.alignof})}} {\memgloref{}}|memjustarg}{136} -\glossaryentry{expr.unary.noexcept@ {\memgloterm{expr.unary.noexcept}}{\memglodesc{(\ref {expr.unary.noexcept})}} {\memgloref{}}|memjustarg}{137} -\glossaryentry{expr.new@ {\memgloterm{expr.new}}{\memglodesc{(\ref {expr.new})}} {\memgloref{}}|memjustarg}{137} -\glossaryentry{expr.delete@ {\memgloterm{expr.delete}}{\memglodesc{(\ref {expr.delete})}} {\memgloref{}}|memjustarg}{141} -\glossaryentry{expr.cast@ {\memgloterm{expr.cast}}{\memglodesc{(\ref {expr.cast})}} {\memgloref{}}|memjustarg}{143} -\glossaryentry{expr.mptr.oper@ {\memgloterm{expr.mptr.oper}}{\memglodesc{(\ref {expr.mptr.oper})}} {\memgloref{}}|memjustarg}{144} -\glossaryentry{expr.mul@ {\memgloterm{expr.mul}}{\memglodesc{(\ref {expr.mul})}} {\memgloref{}}|memjustarg}{145} -\glossaryentry{expr.add@ {\memgloterm{expr.add}}{\memglodesc{(\ref {expr.add})}} {\memgloref{}}|memjustarg}{145} -\glossaryentry{expr.shift@ {\memgloterm{expr.shift}}{\memglodesc{(\ref {expr.shift})}} {\memgloref{}}|memjustarg}{146} -\glossaryentry{expr.spaceship@ {\memgloterm{expr.spaceship}}{\memglodesc{(\ref {expr.spaceship})}} {\memgloref{}}|memjustarg}{147} -\glossaryentry{expr.rel@ {\memgloterm{expr.rel}}{\memglodesc{(\ref {expr.rel})}} {\memgloref{}}|memjustarg}{147} -\glossaryentry{expr.eq@ {\memgloterm{expr.eq}}{\memglodesc{(\ref {expr.eq})}} {\memgloref{}}|memjustarg}{148} -\glossaryentry{expr.bit.and@ {\memgloterm{expr.bit.and}}{\memglodesc{(\ref {expr.bit.and})}} {\memgloref{}}|memjustarg}{149} -\glossaryentry{expr.xor@ {\memgloterm{expr.xor}}{\memglodesc{(\ref {expr.xor})}} {\memgloref{}}|memjustarg}{149} -\glossaryentry{expr.or@ {\memgloterm{expr.or}}{\memglodesc{(\ref {expr.or})}} {\memgloref{}}|memjustarg}{150} -\glossaryentry{expr.log.and@ {\memgloterm{expr.log.and}}{\memglodesc{(\ref {expr.log.and})}} {\memgloref{}}|memjustarg}{150} -\glossaryentry{expr.log.or@ {\memgloterm{expr.log.or}}{\memglodesc{(\ref {expr.log.or})}} {\memgloref{}}|memjustarg}{150} -\glossaryentry{expr.cond@ {\memgloterm{expr.cond}}{\memglodesc{(\ref {expr.cond})}} {\memgloref{}}|memjustarg}{150} -\glossaryentry{expr.yield@ {\memgloterm{expr.yield}}{\memglodesc{(\ref {expr.yield})}} {\memgloref{}}|memjustarg}{152} -\glossaryentry{expr.throw@ {\memgloterm{expr.throw}}{\memglodesc{(\ref {expr.throw})}} {\memgloref{}}|memjustarg}{152} -\glossaryentry{expr.ass@ {\memgloterm{expr.ass}}{\memglodesc{(\ref {expr.ass})}} {\memgloref{}}|memjustarg}{153} -\glossaryentry{expr.comma@ {\memgloterm{expr.comma}}{\memglodesc{(\ref {expr.comma})}} {\memgloref{}}|memjustarg}{154} -\glossaryentry{expr.const@ {\memgloterm{expr.const}}{\memglodesc{(\ref {expr.const})}} {\memgloref{}}|memjustarg}{154} -\glossaryentry{stmt.stmt@ {\memgloterm{stmt.stmt}}{\memglodesc{(\ref {stmt.stmt})}} {\memgloref{}}|memjustarg}{163} -\glossaryentry{stmt.pre@ {\memgloterm{stmt.pre}}{\memglodesc{(\ref {stmt.pre})}} {\memgloref{}}|memjustarg}{163} -\glossaryentry{stmt.label@ {\memgloterm{stmt.label}}{\memglodesc{(\ref {stmt.label})}} {\memgloref{}}|memjustarg}{164} -\glossaryentry{stmt.expr@ {\memgloterm{stmt.expr}}{\memglodesc{(\ref {stmt.expr})}} {\memgloref{}}|memjustarg}{164} -\glossaryentry{stmt.block@ {\memgloterm{stmt.block}}{\memglodesc{(\ref {stmt.block})}} {\memgloref{}}|memjustarg}{164} -\glossaryentry{stmt.select@ {\memgloterm{stmt.select}}{\memglodesc{(\ref {stmt.select})}} {\memgloref{}}|memjustarg}{164} -\glossaryentry{stmt.select.general@ {\memgloterm{stmt.select.general}}{\memglodesc{(\ref {stmt.select.general})}} {\memgloref{}}|memjustarg}{164} -\glossaryentry{stmt.if@ {\memgloterm{stmt.if}}{\memglodesc{(\ref {stmt.if})}} {\memgloref{}}|memjustarg}{165} -\glossaryentry{stmt.switch@ {\memgloterm{stmt.switch}}{\memglodesc{(\ref {stmt.switch})}} {\memgloref{}}|memjustarg}{166} -\glossaryentry{stmt.iter@ {\memgloterm{stmt.iter}}{\memglodesc{(\ref {stmt.iter})}} {\memgloref{}}|memjustarg}{167} -\glossaryentry{stmt.iter.general@ {\memgloterm{stmt.iter.general}}{\memglodesc{(\ref {stmt.iter.general})}} {\memgloref{}}|memjustarg}{167} -\glossaryentry{stmt.while@ {\memgloterm{stmt.while}}{\memglodesc{(\ref {stmt.while})}} {\memgloref{}}|memjustarg}{167} -\glossaryentry{stmt.do@ {\memgloterm{stmt.do}}{\memglodesc{(\ref {stmt.do})}} {\memgloref{}}|memjustarg}{168} -\glossaryentry{stmt.for@ {\memgloterm{stmt.for}}{\memglodesc{(\ref {stmt.for})}} {\memgloref{}}|memjustarg}{168} -\glossaryentry{stmt.ranged@ {\memgloterm{stmt.ranged}}{\memglodesc{(\ref {stmt.ranged})}} {\memgloref{}}|memjustarg}{168} -\glossaryentry{stmt.jump@ {\memgloterm{stmt.jump}}{\memglodesc{(\ref {stmt.jump})}} {\memgloref{}}|memjustarg}{169} -\glossaryentry{stmt.jump.general@ {\memgloterm{stmt.jump.general}}{\memglodesc{(\ref {stmt.jump.general})}} {\memgloref{}}|memjustarg}{169} -\glossaryentry{stmt.break@ {\memgloterm{stmt.break}}{\memglodesc{(\ref {stmt.break})}} {\memgloref{}}|memjustarg}{169} -\glossaryentry{stmt.cont@ {\memgloterm{stmt.cont}}{\memglodesc{(\ref {stmt.cont})}} {\memgloref{}}|memjustarg}{169} -\glossaryentry{stmt.return@ {\memgloterm{stmt.return}}{\memglodesc{(\ref {stmt.return})}} {\memgloref{}}|memjustarg}{170} -\glossaryentry{stmt.return.coroutine@ {\memgloterm{stmt.return.coroutine}}{\memglodesc{(\ref {stmt.return.coroutine})}} {\memgloref{}}|memjustarg}{170} -\glossaryentry{stmt.goto@ {\memgloterm{stmt.goto}}{\memglodesc{(\ref {stmt.goto})}} {\memgloref{}}|memjustarg}{171} -\glossaryentry{stmt.dcl@ {\memgloterm{stmt.dcl}}{\memglodesc{(\ref {stmt.dcl})}} {\memgloref{}}|memjustarg}{171} -\glossaryentry{stmt.ambig@ {\memgloterm{stmt.ambig}}{\memglodesc{(\ref {stmt.ambig})}} {\memgloref{}}|memjustarg}{172} -\glossaryentry{dcl.dcl@ {\memgloterm{dcl.dcl}}{\memglodesc{(\ref {dcl.dcl})}} {\memgloref{}}|memjustarg}{173} -\glossaryentry{dcl.pre@ {\memgloterm{dcl.pre}}{\memglodesc{(\ref {dcl.pre})}} {\memgloref{}}|memjustarg}{173} -\glossaryentry{dcl.spec@ {\memgloterm{dcl.spec}}{\memglodesc{(\ref {dcl.spec})}} {\memgloref{}}|memjustarg}{175} -\glossaryentry{dcl.spec.general@ {\memgloterm{dcl.spec.general}}{\memglodesc{(\ref {dcl.spec.general})}} {\memgloref{}}|memjustarg}{175} -\glossaryentry{dcl.stc@ {\memgloterm{dcl.stc}}{\memglodesc{(\ref {dcl.stc})}} {\memgloref{}}|memjustarg}{176} -\glossaryentry{dcl.fct.spec@ {\memgloterm{dcl.fct.spec}}{\memglodesc{(\ref {dcl.fct.spec})}} {\memgloref{}}|memjustarg}{178} -\glossaryentry{dcl.typedef@ {\memgloterm{dcl.typedef}}{\memglodesc{(\ref {dcl.typedef})}} {\memgloref{}}|memjustarg}{178} -\glossaryentry{dcl.friend@ {\memgloterm{dcl.friend}}{\memglodesc{(\ref {dcl.friend})}} {\memgloref{}}|memjustarg}{179} -\glossaryentry{dcl.constexpr@ {\memgloterm{dcl.constexpr}}{\memglodesc{(\ref {dcl.constexpr})}} {\memgloref{}}|memjustarg}{179} -\glossaryentry{dcl.constinit@ {\memgloterm{dcl.constinit}}{\memglodesc{(\ref {dcl.constinit})}} {\memgloref{}}|memjustarg}{181} -\glossaryentry{dcl.inline@ {\memgloterm{dcl.inline}}{\memglodesc{(\ref {dcl.inline})}} {\memgloref{}}|memjustarg}{181} -\glossaryentry{dcl.type@ {\memgloterm{dcl.type}}{\memglodesc{(\ref {dcl.type})}} {\memgloref{}}|memjustarg}{182} -\glossaryentry{dcl.type.general@ {\memgloterm{dcl.type.general}}{\memglodesc{(\ref {dcl.type.general})}} {\memgloref{}}|memjustarg}{182} -\glossaryentry{dcl.type.cv@ {\memgloterm{dcl.type.cv}}{\memglodesc{(\ref {dcl.type.cv})}} {\memgloref{}}|memjustarg}{183} -\glossaryentry{dcl.type.simple@ {\memgloterm{dcl.type.simple}}{\memglodesc{(\ref {dcl.type.simple})}} {\memgloref{}}|memjustarg}{184} -\glossaryentry{dcl.type.elab@ {\memgloterm{dcl.type.elab}}{\memglodesc{(\ref {dcl.type.elab})}} {\memgloref{}}|memjustarg}{184} -\glossaryentry{dcl.type.decltype@ {\memgloterm{dcl.type.decltype}}{\memglodesc{(\ref {dcl.type.decltype})}} {\memgloref{}}|memjustarg}{186} -\glossaryentry{dcl.spec.auto@ {\memgloterm{dcl.spec.auto}}{\memglodesc{(\ref {dcl.spec.auto})}} {\memgloref{}}|memjustarg}{187} -\glossaryentry{dcl.spec.auto.general@ {\memgloterm{dcl.spec.auto.general}}{\memglodesc{(\ref {dcl.spec.auto.general})}} {\memgloref{}}|memjustarg}{187} -\glossaryentry{dcl.type.auto.deduct@ {\memgloterm{dcl.type.auto.deduct}}{\memglodesc{(\ref {dcl.type.auto.deduct})}} {\memgloref{}}|memjustarg}{190} -\glossaryentry{dcl.type.class.deduct@ {\memgloterm{dcl.type.class.deduct}}{\memglodesc{(\ref {dcl.type.class.deduct})}} {\memgloref{}}|memjustarg}{191} -\glossaryentry{dcl.decl@ {\memgloterm{dcl.decl}}{\memglodesc{(\ref {dcl.decl})}} {\memgloref{}}|memjustarg}{192} -\glossaryentry{dcl.decl.general@ {\memgloterm{dcl.decl.general}}{\memglodesc{(\ref {dcl.decl.general})}} {\memgloref{}}|memjustarg}{192} -\glossaryentry{dcl.name@ {\memgloterm{dcl.name}}{\memglodesc{(\ref {dcl.name})}} {\memgloref{}}|memjustarg}{193} -\glossaryentry{dcl.ambig.res@ {\memgloterm{dcl.ambig.res}}{\memglodesc{(\ref {dcl.ambig.res})}} {\memgloref{}}|memjustarg}{194} -\glossaryentry{dcl.meaning@ {\memgloterm{dcl.meaning}}{\memglodesc{(\ref {dcl.meaning})}} {\memgloref{}}|memjustarg}{195} -\glossaryentry{dcl.meaning.general@ {\memgloterm{dcl.meaning.general}}{\memglodesc{(\ref {dcl.meaning.general})}} {\memgloref{}}|memjustarg}{195} -\glossaryentry{dcl.ptr@ {\memgloterm{dcl.ptr}}{\memglodesc{(\ref {dcl.ptr})}} {\memgloref{}}|memjustarg}{197} -\glossaryentry{dcl.ref@ {\memgloterm{dcl.ref}}{\memglodesc{(\ref {dcl.ref})}} {\memgloref{}}|memjustarg}{198} -\glossaryentry{dcl.mptr@ {\memgloterm{dcl.mptr}}{\memglodesc{(\ref {dcl.mptr})}} {\memgloref{}}|memjustarg}{199} -\glossaryentry{dcl.array@ {\memgloterm{dcl.array}}{\memglodesc{(\ref {dcl.array})}} {\memgloref{}}|memjustarg}{200} -\glossaryentry{dcl.fct@ {\memgloterm{dcl.fct}}{\memglodesc{(\ref {dcl.fct})}} {\memgloref{}}|memjustarg}{201} -\glossaryentry{dcl.fct.default@ {\memgloterm{dcl.fct.default}}{\memglodesc{(\ref {dcl.fct.default})}} {\memgloref{}}|memjustarg}{206} -\glossaryentry{dcl.init@ {\memgloterm{dcl.init}}{\memglodesc{(\ref {dcl.init})}} {\memgloref{}}|memjustarg}{209} -\glossaryentry{dcl.init.general@ {\memgloterm{dcl.init.general}}{\memglodesc{(\ref {dcl.init.general})}} {\memgloref{}}|memjustarg}{209} -\glossaryentry{dcl.init.aggr@ {\memgloterm{dcl.init.aggr}}{\memglodesc{(\ref {dcl.init.aggr})}} {\memgloref{}}|memjustarg}{213} -\glossaryentry{dcl.init.string@ {\memgloterm{dcl.init.string}}{\memglodesc{(\ref {dcl.init.string})}} {\memgloref{}}|memjustarg}{217} -\glossaryentry{dcl.init.ref@ {\memgloterm{dcl.init.ref}}{\memglodesc{(\ref {dcl.init.ref})}} {\memgloref{}}|memjustarg}{218} -\glossaryentry{dcl.init.list@ {\memgloterm{dcl.init.list}}{\memglodesc{(\ref {dcl.init.list})}} {\memgloref{}}|memjustarg}{220} -\glossaryentry{dcl.fct.def@ {\memgloterm{dcl.fct.def}}{\memglodesc{(\ref {dcl.fct.def})}} {\memgloref{}}|memjustarg}{225} -\glossaryentry{dcl.fct.def.general@ {\memgloterm{dcl.fct.def.general}}{\memglodesc{(\ref {dcl.fct.def.general})}} {\memgloref{}}|memjustarg}{225} -\glossaryentry{dcl.fct.def.default@ {\memgloterm{dcl.fct.def.default}}{\memglodesc{(\ref {dcl.fct.def.default})}} {\memgloref{}}|memjustarg}{226} -\glossaryentry{dcl.fct.def.delete@ {\memgloterm{dcl.fct.def.delete}}{\memglodesc{(\ref {dcl.fct.def.delete})}} {\memgloref{}}|memjustarg}{227} -\glossaryentry{dcl.fct.def.coroutine@ {\memgloterm{dcl.fct.def.coroutine}}{\memglodesc{(\ref {dcl.fct.def.coroutine})}} {\memgloref{}}|memjustarg}{228} -\glossaryentry{dcl.struct.bind@ {\memgloterm{dcl.struct.bind}}{\memglodesc{(\ref {dcl.struct.bind})}} {\memgloref{}}|memjustarg}{231} -\glossaryentry{enum@ {\memgloterm{enum}}{\memglodesc{(\ref {enum})}} {\memgloref{}}|memjustarg}{232} -\glossaryentry{dcl.enum@ {\memgloterm{dcl.enum}}{\memglodesc{(\ref {dcl.enum})}} {\memgloref{}}|memjustarg}{232} -\glossaryentry{enum.udecl@ {\memgloterm{enum.udecl}}{\memglodesc{(\ref {enum.udecl})}} {\memgloref{}}|memjustarg}{235} -\glossaryentry{basic.namespace@ {\memgloterm{basic.namespace}}{\memglodesc{(\ref {basic.namespace})}} {\memgloref{}}|memjustarg}{235} -\glossaryentry{basic.namespace.general@ {\memgloterm{basic.namespace.general}}{\memglodesc{(\ref {basic.namespace.general})}} {\memgloref{}}|memjustarg}{235} -\glossaryentry{namespace.def@ {\memgloterm{namespace.def}}{\memglodesc{(\ref {namespace.def})}} {\memgloref{}}|memjustarg}{236} -\glossaryentry{namespace.def.general@ {\memgloterm{namespace.def.general}}{\memglodesc{(\ref {namespace.def.general})}} {\memgloref{}}|memjustarg}{236} -\glossaryentry{namespace.unnamed@ {\memgloterm{namespace.unnamed}}{\memglodesc{(\ref {namespace.unnamed})}} {\memgloref{}}|memjustarg}{237} -\glossaryentry{namespace.alias@ {\memgloterm{namespace.alias}}{\memglodesc{(\ref {namespace.alias})}} {\memgloref{}}|memjustarg}{238} -\glossaryentry{namespace.udir@ {\memgloterm{namespace.udir}}{\memglodesc{(\ref {namespace.udir})}} {\memgloref{}}|memjustarg}{238} -\glossaryentry{namespace.udecl@ {\memgloterm{namespace.udecl}}{\memglodesc{(\ref {namespace.udecl})}} {\memgloref{}}|memjustarg}{240} -\glossaryentry{dcl.asm@ {\memgloterm{dcl.asm}}{\memglodesc{(\ref {dcl.asm})}} {\memgloref{}}|memjustarg}{245} -\glossaryentry{dcl.link@ {\memgloterm{dcl.link}}{\memglodesc{(\ref {dcl.link})}} {\memgloref{}}|memjustarg}{245} -\glossaryentry{dcl.attr@ {\memgloterm{dcl.attr}}{\memglodesc{(\ref {dcl.attr})}} {\memgloref{}}|memjustarg}{247} -\glossaryentry{dcl.attr.grammar@ {\memgloterm{dcl.attr.grammar}}{\memglodesc{(\ref {dcl.attr.grammar})}} {\memgloref{}}|memjustarg}{247} -\glossaryentry{dcl.align@ {\memgloterm{dcl.align}}{\memglodesc{(\ref {dcl.align})}} {\memgloref{}}|memjustarg}{249} -\glossaryentry{dcl.attr.assume@ {\memgloterm{dcl.attr.assume}}{\memglodesc{(\ref {dcl.attr.assume})}} {\memgloref{}}|memjustarg}{250} -\glossaryentry{dcl.attr.depend@ {\memgloterm{dcl.attr.depend}}{\memglodesc{(\ref {dcl.attr.depend})}} {\memgloref{}}|memjustarg}{250} -\glossaryentry{dcl.attr.deprecated@ {\memgloterm{dcl.attr.deprecated}}{\memglodesc{(\ref {dcl.attr.deprecated})}} {\memgloref{}}|memjustarg}{251} -\glossaryentry{dcl.attr.fallthrough@ {\memgloterm{dcl.attr.fallthrough}}{\memglodesc{(\ref {dcl.attr.fallthrough})}} {\memgloref{}}|memjustarg}{251} -\glossaryentry{dcl.attr.likelihood@ {\memgloterm{dcl.attr.likelihood}}{\memglodesc{(\ref {dcl.attr.likelihood})}} {\memgloref{}}|memjustarg}{252} -\glossaryentry{dcl.attr.unused@ {\memgloterm{dcl.attr.unused}}{\memglodesc{(\ref {dcl.attr.unused})}} {\memgloref{}}|memjustarg}{253} -\glossaryentry{dcl.attr.nodiscard@ {\memgloterm{dcl.attr.nodiscard}}{\memglodesc{(\ref {dcl.attr.nodiscard})}} {\memgloref{}}|memjustarg}{253} -\glossaryentry{dcl.attr.noreturn@ {\memgloterm{dcl.attr.noreturn}}{\memglodesc{(\ref {dcl.attr.noreturn})}} {\memgloref{}}|memjustarg}{254} -\glossaryentry{dcl.attr.nouniqueaddr@ {\memgloterm{dcl.attr.nouniqueaddr}}{\memglodesc{(\ref {dcl.attr.nouniqueaddr})}} {\memgloref{}}|memjustarg}{254} -\glossaryentry{module@ {\memgloterm{module}}{\memglodesc{(\ref {module})}} {\memgloref{}}|memjustarg}{256} -\glossaryentry{module.unit@ {\memgloterm{module.unit}}{\memglodesc{(\ref {module.unit})}} {\memgloref{}}|memjustarg}{256} -\glossaryentry{module.interface@ {\memgloterm{module.interface}}{\memglodesc{(\ref {module.interface})}} {\memgloref{}}|memjustarg}{257} -\glossaryentry{module.import@ {\memgloterm{module.import}}{\memglodesc{(\ref {module.import})}} {\memgloref{}}|memjustarg}{260} -\glossaryentry{module.global.frag@ {\memgloterm{module.global.frag}}{\memglodesc{(\ref {module.global.frag})}} {\memgloref{}}|memjustarg}{261} -\glossaryentry{module.private.frag@ {\memgloterm{module.private.frag}}{\memglodesc{(\ref {module.private.frag})}} {\memgloref{}}|memjustarg}{263} -\glossaryentry{module.context@ {\memgloterm{module.context}}{\memglodesc{(\ref {module.context})}} {\memgloref{}}|memjustarg}{264} -\glossaryentry{module.reach@ {\memgloterm{module.reach}}{\memglodesc{(\ref {module.reach})}} {\memgloref{}}|memjustarg}{265} -\glossaryentry{class@ {\memgloterm{class}}{\memglodesc{(\ref {class})}} {\memgloref{}}|memjustarg}{267} -\glossaryentry{class.pre@ {\memgloterm{class.pre}}{\memglodesc{(\ref {class.pre})}} {\memgloref{}}|memjustarg}{267} -\glossaryentry{class.prop@ {\memgloterm{class.prop}}{\memglodesc{(\ref {class.prop})}} {\memgloref{}}|memjustarg}{268} -\glossaryentry{class.name@ {\memgloterm{class.name}}{\memglodesc{(\ref {class.name})}} {\memgloref{}}|memjustarg}{269} -\glossaryentry{class.mem@ {\memgloterm{class.mem}}{\memglodesc{(\ref {class.mem})}} {\memgloref{}}|memjustarg}{271} -\glossaryentry{class.mem.general@ {\memgloterm{class.mem.general}}{\memglodesc{(\ref {class.mem.general})}} {\memgloref{}}|memjustarg}{271} -\glossaryentry{class.mfct@ {\memgloterm{class.mfct}}{\memglodesc{(\ref {class.mfct})}} {\memgloref{}}|memjustarg}{274} -\glossaryentry{class.mfct.non.static@ {\memgloterm{class.mfct.non.static}}{\memglodesc{(\ref {class.mfct.non.static})}} {\memgloref{}}|memjustarg}{275} -\glossaryentry{special@ {\memgloterm{special}}{\memglodesc{(\ref {special})}} {\memgloref{}}|memjustarg}{276} -\glossaryentry{class.ctor@ {\memgloterm{class.ctor}}{\memglodesc{(\ref {class.ctor})}} {\memgloref{}}|memjustarg}{277} -\glossaryentry{class.ctor.general@ {\memgloterm{class.ctor.general}}{\memglodesc{(\ref {class.ctor.general})}} {\memgloref{}}|memjustarg}{277} -\glossaryentry{class.default.ctor@ {\memgloterm{class.default.ctor}}{\memglodesc{(\ref {class.default.ctor})}} {\memgloref{}}|memjustarg}{277} -\glossaryentry{class.copy.ctor@ {\memgloterm{class.copy.ctor}}{\memglodesc{(\ref {class.copy.ctor})}} {\memgloref{}}|memjustarg}{278} -\glossaryentry{class.copy.assign@ {\memgloterm{class.copy.assign}}{\memglodesc{(\ref {class.copy.assign})}} {\memgloref{}}|memjustarg}{281} -\glossaryentry{class.dtor@ {\memgloterm{class.dtor}}{\memglodesc{(\ref {class.dtor})}} {\memgloref{}}|memjustarg}{283} -\glossaryentry{class.conv@ {\memgloterm{class.conv}}{\memglodesc{(\ref {class.conv})}} {\memgloref{}}|memjustarg}{286} -\glossaryentry{class.conv.general@ {\memgloterm{class.conv.general}}{\memglodesc{(\ref {class.conv.general})}} {\memgloref{}}|memjustarg}{286} -\glossaryentry{class.conv.ctor@ {\memgloterm{class.conv.ctor}}{\memglodesc{(\ref {class.conv.ctor})}} {\memgloref{}}|memjustarg}{286} -\glossaryentry{class.conv.fct@ {\memgloterm{class.conv.fct}}{\memglodesc{(\ref {class.conv.fct})}} {\memgloref{}}|memjustarg}{287} -\glossaryentry{class.static@ {\memgloterm{class.static}}{\memglodesc{(\ref {class.static})}} {\memgloref{}}|memjustarg}{289} -\glossaryentry{class.static.general@ {\memgloterm{class.static.general}}{\memglodesc{(\ref {class.static.general})}} {\memgloref{}}|memjustarg}{289} -\glossaryentry{class.static.mfct@ {\memgloterm{class.static.mfct}}{\memglodesc{(\ref {class.static.mfct})}} {\memgloref{}}|memjustarg}{289} -\glossaryentry{class.static.data@ {\memgloterm{class.static.data}}{\memglodesc{(\ref {class.static.data})}} {\memgloref{}}|memjustarg}{289} -\glossaryentry{class.bit@ {\memgloterm{class.bit}}{\memglodesc{(\ref {class.bit})}} {\memgloref{}}|memjustarg}{290} -\glossaryentry{class.free@ {\memgloterm{class.free}}{\memglodesc{(\ref {class.free})}} {\memgloref{}}|memjustarg}{291} -\glossaryentry{class.nest@ {\memgloterm{class.nest}}{\memglodesc{(\ref {class.nest})}} {\memgloref{}}|memjustarg}{292} -\glossaryentry{class.union@ {\memgloterm{class.union}}{\memglodesc{(\ref {class.union})}} {\memgloref{}}|memjustarg}{293} -\glossaryentry{class.union.general@ {\memgloterm{class.union.general}}{\memglodesc{(\ref {class.union.general})}} {\memgloref{}}|memjustarg}{293} -\glossaryentry{class.union.anon@ {\memgloterm{class.union.anon}}{\memglodesc{(\ref {class.union.anon})}} {\memgloref{}}|memjustarg}{294} -\glossaryentry{class.local@ {\memgloterm{class.local}}{\memglodesc{(\ref {class.local})}} {\memgloref{}}|memjustarg}{295} -\glossaryentry{class.derived@ {\memgloterm{class.derived}}{\memglodesc{(\ref {class.derived})}} {\memgloref{}}|memjustarg}{296} -\glossaryentry{class.derived.general@ {\memgloterm{class.derived.general}}{\memglodesc{(\ref {class.derived.general})}} {\memgloref{}}|memjustarg}{296} -\glossaryentry{class.mi@ {\memgloterm{class.mi}}{\memglodesc{(\ref {class.mi})}} {\memgloref{}}|memjustarg}{297} -\glossaryentry{class.virtual@ {\memgloterm{class.virtual}}{\memglodesc{(\ref {class.virtual})}} {\memgloref{}}|memjustarg}{299} -\glossaryentry{class.abstract@ {\memgloterm{class.abstract}}{\memglodesc{(\ref {class.abstract})}} {\memgloref{}}|memjustarg}{303} -\glossaryentry{class.access@ {\memgloterm{class.access}}{\memglodesc{(\ref {class.access})}} {\memgloref{}}|memjustarg}{304} -\glossaryentry{class.access.general@ {\memgloterm{class.access.general}}{\memglodesc{(\ref {class.access.general})}} {\memgloref{}}|memjustarg}{304} -\glossaryentry{class.access.spec@ {\memgloterm{class.access.spec}}{\memglodesc{(\ref {class.access.spec})}} {\memgloref{}}|memjustarg}{306} -\glossaryentry{class.access.base@ {\memgloterm{class.access.base}}{\memglodesc{(\ref {class.access.base})}} {\memgloref{}}|memjustarg}{307} -\glossaryentry{class.friend@ {\memgloterm{class.friend}}{\memglodesc{(\ref {class.friend})}} {\memgloref{}}|memjustarg}{309} -\glossaryentry{class.protected@ {\memgloterm{class.protected}}{\memglodesc{(\ref {class.protected})}} {\memgloref{}}|memjustarg}{312} -\glossaryentry{class.access.virt@ {\memgloterm{class.access.virt}}{\memglodesc{(\ref {class.access.virt})}} {\memgloref{}}|memjustarg}{313} -\glossaryentry{class.paths@ {\memgloterm{class.paths}}{\memglodesc{(\ref {class.paths})}} {\memgloref{}}|memjustarg}{313} -\glossaryentry{class.access.nest@ {\memgloterm{class.access.nest}}{\memglodesc{(\ref {class.access.nest})}} {\memgloref{}}|memjustarg}{313} -\glossaryentry{class.init@ {\memgloterm{class.init}}{\memglodesc{(\ref {class.init})}} {\memgloref{}}|memjustarg}{314} -\glossaryentry{class.init.general@ {\memgloterm{class.init.general}}{\memglodesc{(\ref {class.init.general})}} {\memgloref{}}|memjustarg}{314} -\glossaryentry{class.expl.init@ {\memgloterm{class.expl.init}}{\memglodesc{(\ref {class.expl.init})}} {\memgloref{}}|memjustarg}{314} -\glossaryentry{class.base.init@ {\memgloterm{class.base.init}}{\memglodesc{(\ref {class.base.init})}} {\memgloref{}}|memjustarg}{315} -\glossaryentry{class.inhctor.init@ {\memgloterm{class.inhctor.init}}{\memglodesc{(\ref {class.inhctor.init})}} {\memgloref{}}|memjustarg}{319} -\glossaryentry{class.cdtor@ {\memgloterm{class.cdtor}}{\memglodesc{(\ref {class.cdtor})}} {\memgloref{}}|memjustarg}{320} -\glossaryentry{class.copy.elision@ {\memgloterm{class.copy.elision}}{\memglodesc{(\ref {class.copy.elision})}} {\memgloref{}}|memjustarg}{323} -\glossaryentry{class.compare@ {\memgloterm{class.compare}}{\memglodesc{(\ref {class.compare})}} {\memgloref{}}|memjustarg}{325} -\glossaryentry{class.compare.default@ {\memgloterm{class.compare.default}}{\memglodesc{(\ref {class.compare.default})}} {\memgloref{}}|memjustarg}{325} -\glossaryentry{class.eq@ {\memgloterm{class.eq}}{\memglodesc{(\ref {class.eq})}} {\memgloref{}}|memjustarg}{326} -\glossaryentry{class.spaceship@ {\memgloterm{class.spaceship}}{\memglodesc{(\ref {class.spaceship})}} {\memgloref{}}|memjustarg}{327} -\glossaryentry{class.compare.secondary@ {\memgloterm{class.compare.secondary}}{\memglodesc{(\ref {class.compare.secondary})}} {\memgloref{}}|memjustarg}{327} -\glossaryentry{over@ {\memgloterm{over}}{\memglodesc{(\ref {over})}} {\memgloref{}}|memjustarg}{329} -\glossaryentry{over.pre@ {\memgloterm{over.pre}}{\memglodesc{(\ref {over.pre})}} {\memgloref{}}|memjustarg}{329} -\glossaryentry{over.match@ {\memgloterm{over.match}}{\memglodesc{(\ref {over.match})}} {\memgloref{}}|memjustarg}{329} -\glossaryentry{over.match.general@ {\memgloterm{over.match.general}}{\memglodesc{(\ref {over.match.general})}} {\memgloref{}}|memjustarg}{329} -\glossaryentry{over.match.funcs@ {\memgloterm{over.match.funcs}}{\memglodesc{(\ref {over.match.funcs})}} {\memgloref{}}|memjustarg}{330} -\glossaryentry{over.match.funcs.general@ {\memgloterm{over.match.funcs.general}}{\memglodesc{(\ref {over.match.funcs.general})}} {\memgloref{}}|memjustarg}{330} -\glossaryentry{over.match.call@ {\memgloterm{over.match.call}}{\memglodesc{(\ref {over.match.call})}} {\memgloref{}}|memjustarg}{331} -\glossaryentry{over.match.call.general@ {\memgloterm{over.match.call.general}}{\memglodesc{(\ref {over.match.call.general})}} {\memgloref{}}|memjustarg}{331} -\glossaryentry{over.call.func@ {\memgloterm{over.call.func}}{\memglodesc{(\ref {over.call.func})}} {\memgloref{}}|memjustarg}{332} -\glossaryentry{over.call.object@ {\memgloterm{over.call.object}}{\memglodesc{(\ref {over.call.object})}} {\memgloref{}}|memjustarg}{333} -\glossaryentry{over.match.oper@ {\memgloterm{over.match.oper}}{\memglodesc{(\ref {over.match.oper})}} {\memgloref{}}|memjustarg}{334} -\glossaryentry{over.match.ctor@ {\memgloterm{over.match.ctor}}{\memglodesc{(\ref {over.match.ctor})}} {\memgloref{}}|memjustarg}{337} -\glossaryentry{over.match.copy@ {\memgloterm{over.match.copy}}{\memglodesc{(\ref {over.match.copy})}} {\memgloref{}}|memjustarg}{337} -\glossaryentry{over.match.conv@ {\memgloterm{over.match.conv}}{\memglodesc{(\ref {over.match.conv})}} {\memgloref{}}|memjustarg}{337} -\glossaryentry{over.match.ref@ {\memgloterm{over.match.ref}}{\memglodesc{(\ref {over.match.ref})}} {\memgloref{}}|memjustarg}{338} -\glossaryentry{over.match.list@ {\memgloterm{over.match.list}}{\memglodesc{(\ref {over.match.list})}} {\memgloref{}}|memjustarg}{338} -\glossaryentry{over.match.class.deduct@ {\memgloterm{over.match.class.deduct}}{\memglodesc{(\ref {over.match.class.deduct})}} {\memgloref{}}|memjustarg}{338} -\glossaryentry{over.match.viable@ {\memgloterm{over.match.viable}}{\memglodesc{(\ref {over.match.viable})}} {\memgloref{}}|memjustarg}{343} -\glossaryentry{over.match.best@ {\memgloterm{over.match.best}}{\memglodesc{(\ref {over.match.best})}} {\memgloref{}}|memjustarg}{343} -\glossaryentry{over.match.best.general@ {\memgloterm{over.match.best.general}}{\memglodesc{(\ref {over.match.best.general})}} {\memgloref{}}|memjustarg}{343} -\glossaryentry{over.best.ics@ {\memgloterm{over.best.ics}}{\memglodesc{(\ref {over.best.ics})}} {\memgloref{}}|memjustarg}{346} -\glossaryentry{over.best.ics.general@ {\memgloterm{over.best.ics.general}}{\memglodesc{(\ref {over.best.ics.general})}} {\memgloref{}}|memjustarg}{346} -\glossaryentry{over.ics.scs@ {\memgloterm{over.ics.scs}}{\memglodesc{(\ref {over.ics.scs})}} {\memgloref{}}|memjustarg}{348} -\glossaryentry{over.ics.user@ {\memgloterm{over.ics.user}}{\memglodesc{(\ref {over.ics.user})}} {\memgloref{}}|memjustarg}{348} -\glossaryentry{over.ics.ellipsis@ {\memgloterm{over.ics.ellipsis}}{\memglodesc{(\ref {over.ics.ellipsis})}} {\memgloref{}}|memjustarg}{349} -\glossaryentry{over.ics.ref@ {\memgloterm{over.ics.ref}}{\memglodesc{(\ref {over.ics.ref})}} {\memgloref{}}|memjustarg}{349} -\glossaryentry{over.ics.list@ {\memgloterm{over.ics.list}}{\memglodesc{(\ref {over.ics.list})}} {\memgloref{}}|memjustarg}{349} -\glossaryentry{over.ics.rank@ {\memgloterm{over.ics.rank}}{\memglodesc{(\ref {over.ics.rank})}} {\memgloref{}}|memjustarg}{352} -\glossaryentry{over.over@ {\memgloterm{over.over}}{\memglodesc{(\ref {over.over})}} {\memgloref{}}|memjustarg}{355} -\glossaryentry{over.oper@ {\memgloterm{over.oper}}{\memglodesc{(\ref {over.oper})}} {\memgloref{}}|memjustarg}{356} -\glossaryentry{over.oper.general@ {\memgloterm{over.oper.general}}{\memglodesc{(\ref {over.oper.general})}} {\memgloref{}}|memjustarg}{356} -\glossaryentry{over.unary@ {\memgloterm{over.unary}}{\memglodesc{(\ref {over.unary})}} {\memgloref{}}|memjustarg}{358} -\glossaryentry{over.binary@ {\memgloterm{over.binary}}{\memglodesc{(\ref {over.binary})}} {\memgloref{}}|memjustarg}{358} -\glossaryentry{over.binary.general@ {\memgloterm{over.binary.general}}{\memglodesc{(\ref {over.binary.general})}} {\memgloref{}}|memjustarg}{358} -\glossaryentry{over.ass@ {\memgloterm{over.ass}}{\memglodesc{(\ref {over.ass})}} {\memgloref{}}|memjustarg}{358} -\glossaryentry{over.call@ {\memgloterm{over.call}}{\memglodesc{(\ref {over.call})}} {\memgloref{}}|memjustarg}{359} -\glossaryentry{over.sub@ {\memgloterm{over.sub}}{\memglodesc{(\ref {over.sub})}} {\memgloref{}}|memjustarg}{359} -\glossaryentry{over.ref@ {\memgloterm{over.ref}}{\memglodesc{(\ref {over.ref})}} {\memgloref{}}|memjustarg}{359} -\glossaryentry{over.inc@ {\memgloterm{over.inc}}{\memglodesc{(\ref {over.inc})}} {\memgloref{}}|memjustarg}{359} -\glossaryentry{over.built@ {\memgloterm{over.built}}{\memglodesc{(\ref {over.built})}} {\memgloref{}}|memjustarg}{360} -\glossaryentry{over.literal@ {\memgloterm{over.literal}}{\memglodesc{(\ref {over.literal})}} {\memgloref{}}|memjustarg}{362} -\glossaryentry{temp@ {\memgloterm{temp}}{\memglodesc{(\ref {temp})}} {\memgloref{}}|memjustarg}{364} -\glossaryentry{temp.pre@ {\memgloterm{temp.pre}}{\memglodesc{(\ref {temp.pre})}} {\memgloref{}}|memjustarg}{364} -\glossaryentry{temp.param@ {\memgloterm{temp.param}}{\memglodesc{(\ref {temp.param})}} {\memgloref{}}|memjustarg}{365} -\glossaryentry{temp.names@ {\memgloterm{temp.names}}{\memglodesc{(\ref {temp.names})}} {\memgloref{}}|memjustarg}{369} -\glossaryentry{temp.arg@ {\memgloterm{temp.arg}}{\memglodesc{(\ref {temp.arg})}} {\memgloref{}}|memjustarg}{372} -\glossaryentry{temp.arg.general@ {\memgloterm{temp.arg.general}}{\memglodesc{(\ref {temp.arg.general})}} {\memgloref{}}|memjustarg}{372} -\glossaryentry{temp.arg.type@ {\memgloterm{temp.arg.type}}{\memglodesc{(\ref {temp.arg.type})}} {\memgloref{}}|memjustarg}{374} -\glossaryentry{temp.arg.nontype@ {\memgloterm{temp.arg.nontype}}{\memglodesc{(\ref {temp.arg.nontype})}} {\memgloref{}}|memjustarg}{374} -\glossaryentry{temp.arg.template@ {\memgloterm{temp.arg.template}}{\memglodesc{(\ref {temp.arg.template})}} {\memgloref{}}|memjustarg}{376} -\glossaryentry{temp.constr@ {\memgloterm{temp.constr}}{\memglodesc{(\ref {temp.constr})}} {\memgloref{}}|memjustarg}{377} -\glossaryentry{temp.constr.general@ {\memgloterm{temp.constr.general}}{\memglodesc{(\ref {temp.constr.general})}} {\memgloref{}}|memjustarg}{377} -\glossaryentry{temp.constr.constr@ {\memgloterm{temp.constr.constr}}{\memglodesc{(\ref {temp.constr.constr})}} {\memgloref{}}|memjustarg}{377} -\glossaryentry{temp.constr.constr.general@ {\memgloterm{temp.constr.constr.general}}{\memglodesc{(\ref {temp.constr.constr.general})}} {\memgloref{}}|memjustarg}{377} -\glossaryentry{temp.constr.op@ {\memgloterm{temp.constr.op}}{\memglodesc{(\ref {temp.constr.op})}} {\memgloref{}}|memjustarg}{378} -\glossaryentry{temp.constr.atomic@ {\memgloterm{temp.constr.atomic}}{\memglodesc{(\ref {temp.constr.atomic})}} {\memgloref{}}|memjustarg}{379} -\glossaryentry{temp.constr.decl@ {\memgloterm{temp.constr.decl}}{\memglodesc{(\ref {temp.constr.decl})}} {\memgloref{}}|memjustarg}{380} -\glossaryentry{temp.constr.normal@ {\memgloterm{temp.constr.normal}}{\memglodesc{(\ref {temp.constr.normal})}} {\memgloref{}}|memjustarg}{381} -\glossaryentry{temp.constr.order@ {\memgloterm{temp.constr.order}}{\memglodesc{(\ref {temp.constr.order})}} {\memgloref{}}|memjustarg}{382} -\glossaryentry{temp.type@ {\memgloterm{temp.type}}{\memglodesc{(\ref {temp.type})}} {\memgloref{}}|memjustarg}{382} -\glossaryentry{temp.decls@ {\memgloterm{temp.decls}}{\memglodesc{(\ref {temp.decls})}} {\memgloref{}}|memjustarg}{383} -\glossaryentry{temp.decls.general@ {\memgloterm{temp.decls.general}}{\memglodesc{(\ref {temp.decls.general})}} {\memgloref{}}|memjustarg}{383} -\glossaryentry{temp.class@ {\memgloterm{temp.class}}{\memglodesc{(\ref {temp.class})}} {\memgloref{}}|memjustarg}{384} -\glossaryentry{temp.class.general@ {\memgloterm{temp.class.general}}{\memglodesc{(\ref {temp.class.general})}} {\memgloref{}}|memjustarg}{384} -\glossaryentry{temp.mem.func@ {\memgloterm{temp.mem.func}}{\memglodesc{(\ref {temp.mem.func})}} {\memgloref{}}|memjustarg}{385} -\glossaryentry{temp.deduct.guide@ {\memgloterm{temp.deduct.guide}}{\memglodesc{(\ref {temp.deduct.guide})}} {\memgloref{}}|memjustarg}{385} -\glossaryentry{temp.mem.class@ {\memgloterm{temp.mem.class}}{\memglodesc{(\ref {temp.mem.class})}} {\memgloref{}}|memjustarg}{386} -\glossaryentry{temp.static@ {\memgloterm{temp.static}}{\memglodesc{(\ref {temp.static})}} {\memgloref{}}|memjustarg}{386} -\glossaryentry{temp.mem.enum@ {\memgloterm{temp.mem.enum}}{\memglodesc{(\ref {temp.mem.enum})}} {\memgloref{}}|memjustarg}{387} -\glossaryentry{temp.mem@ {\memgloterm{temp.mem}}{\memglodesc{(\ref {temp.mem})}} {\memgloref{}}|memjustarg}{387} -\glossaryentry{temp.variadic@ {\memgloterm{temp.variadic}}{\memglodesc{(\ref {temp.variadic})}} {\memgloref{}}|memjustarg}{388} -\glossaryentry{temp.friend@ {\memgloterm{temp.friend}}{\memglodesc{(\ref {temp.friend})}} {\memgloref{}}|memjustarg}{391} -\glossaryentry{temp.spec.partial@ {\memgloterm{temp.spec.partial}}{\memglodesc{(\ref {temp.spec.partial})}} {\memgloref{}}|memjustarg}{393} -\glossaryentry{temp.spec.partial.general@ {\memgloterm{temp.spec.partial.general}}{\memglodesc{(\ref {temp.spec.partial.general})}} {\memgloref{}}|memjustarg}{393} -\glossaryentry{temp.spec.partial.match@ {\memgloterm{temp.spec.partial.match}}{\memglodesc{(\ref {temp.spec.partial.match})}} {\memgloref{}}|memjustarg}{395} -\glossaryentry{temp.spec.partial.order@ {\memgloterm{temp.spec.partial.order}}{\memglodesc{(\ref {temp.spec.partial.order})}} {\memgloref{}}|memjustarg}{396} -\glossaryentry{temp.spec.partial.member@ {\memgloterm{temp.spec.partial.member}}{\memglodesc{(\ref {temp.spec.partial.member})}} {\memgloref{}}|memjustarg}{396} -\glossaryentry{temp.fct@ {\memgloterm{temp.fct}}{\memglodesc{(\ref {temp.fct})}} {\memgloref{}}|memjustarg}{397} -\glossaryentry{temp.fct.general@ {\memgloterm{temp.fct.general}}{\memglodesc{(\ref {temp.fct.general})}} {\memgloref{}}|memjustarg}{397} -\glossaryentry{temp.over.link@ {\memgloterm{temp.over.link}}{\memglodesc{(\ref {temp.over.link})}} {\memgloref{}}|memjustarg}{398} -\glossaryentry{temp.func.order@ {\memgloterm{temp.func.order}}{\memglodesc{(\ref {temp.func.order})}} {\memgloref{}}|memjustarg}{400} -\glossaryentry{temp.alias@ {\memgloterm{temp.alias}}{\memglodesc{(\ref {temp.alias})}} {\memgloref{}}|memjustarg}{403} -\glossaryentry{temp.concept@ {\memgloterm{temp.concept}}{\memglodesc{(\ref {temp.concept})}} {\memgloref{}}|memjustarg}{404} -\glossaryentry{temp.res@ {\memgloterm{temp.res}}{\memglodesc{(\ref {temp.res})}} {\memgloref{}}|memjustarg}{404} -\glossaryentry{temp.res.general@ {\memgloterm{temp.res.general}}{\memglodesc{(\ref {temp.res.general})}} {\memgloref{}}|memjustarg}{404} -\glossaryentry{temp.local@ {\memgloterm{temp.local}}{\memglodesc{(\ref {temp.local})}} {\memgloref{}}|memjustarg}{408} -\glossaryentry{temp.dep@ {\memgloterm{temp.dep}}{\memglodesc{(\ref {temp.dep})}} {\memgloref{}}|memjustarg}{410} -\glossaryentry{temp.dep.general@ {\memgloterm{temp.dep.general}}{\memglodesc{(\ref {temp.dep.general})}} {\memgloref{}}|memjustarg}{410} -\glossaryentry{temp.dep.type@ {\memgloterm{temp.dep.type}}{\memglodesc{(\ref {temp.dep.type})}} {\memgloref{}}|memjustarg}{410} -\glossaryentry{temp.dep.expr@ {\memgloterm{temp.dep.expr}}{\memglodesc{(\ref {temp.dep.expr})}} {\memgloref{}}|memjustarg}{413} -\glossaryentry{temp.dep.constexpr@ {\memgloterm{temp.dep.constexpr}}{\memglodesc{(\ref {temp.dep.constexpr})}} {\memgloref{}}|memjustarg}{414} -\glossaryentry{temp.dep.temp@ {\memgloterm{temp.dep.temp}}{\memglodesc{(\ref {temp.dep.temp})}} {\memgloref{}}|memjustarg}{415} -\glossaryentry{temp.dep.res@ {\memgloterm{temp.dep.res}}{\memglodesc{(\ref {temp.dep.res})}} {\memgloref{}}|memjustarg}{415} -\glossaryentry{temp.point@ {\memgloterm{temp.point}}{\memglodesc{(\ref {temp.point})}} {\memgloref{}}|memjustarg}{415} -\glossaryentry{temp.dep.candidate@ {\memgloterm{temp.dep.candidate}}{\memglodesc{(\ref {temp.dep.candidate})}} {\memgloref{}}|memjustarg}{416} -\glossaryentry{temp.spec@ {\memgloterm{temp.spec}}{\memglodesc{(\ref {temp.spec})}} {\memgloref{}}|memjustarg}{418} -\glossaryentry{temp.spec.general@ {\memgloterm{temp.spec.general}}{\memglodesc{(\ref {temp.spec.general})}} {\memgloref{}}|memjustarg}{418} -\glossaryentry{temp.inst@ {\memgloterm{temp.inst}}{\memglodesc{(\ref {temp.inst})}} {\memgloref{}}|memjustarg}{420} -\glossaryentry{temp.explicit@ {\memgloterm{temp.explicit}}{\memglodesc{(\ref {temp.explicit})}} {\memgloref{}}|memjustarg}{424} -\glossaryentry{temp.expl.spec@ {\memgloterm{temp.expl.spec}}{\memglodesc{(\ref {temp.expl.spec})}} {\memgloref{}}|memjustarg}{426} -\glossaryentry{temp.fct.spec@ {\memgloterm{temp.fct.spec}}{\memglodesc{(\ref {temp.fct.spec})}} {\memgloref{}}|memjustarg}{431} -\glossaryentry{temp.fct.spec.general@ {\memgloterm{temp.fct.spec.general}}{\memglodesc{(\ref {temp.fct.spec.general})}} {\memgloref{}}|memjustarg}{431} -\glossaryentry{temp.arg.explicit@ {\memgloterm{temp.arg.explicit}}{\memglodesc{(\ref {temp.arg.explicit})}} {\memgloref{}}|memjustarg}{431} -\glossaryentry{temp.deduct@ {\memgloterm{temp.deduct}}{\memglodesc{(\ref {temp.deduct})}} {\memgloref{}}|memjustarg}{433} -\glossaryentry{temp.deduct.general@ {\memgloterm{temp.deduct.general}}{\memglodesc{(\ref {temp.deduct.general})}} {\memgloref{}}|memjustarg}{433} -\glossaryentry{temp.deduct.call@ {\memgloterm{temp.deduct.call}}{\memglodesc{(\ref {temp.deduct.call})}} {\memgloref{}}|memjustarg}{437} -\glossaryentry{temp.deduct.funcaddr@ {\memgloterm{temp.deduct.funcaddr}}{\memglodesc{(\ref {temp.deduct.funcaddr})}} {\memgloref{}}|memjustarg}{440} -\glossaryentry{temp.deduct.conv@ {\memgloterm{temp.deduct.conv}}{\memglodesc{(\ref {temp.deduct.conv})}} {\memgloref{}}|memjustarg}{441} -\glossaryentry{temp.deduct.partial@ {\memgloterm{temp.deduct.partial}}{\memglodesc{(\ref {temp.deduct.partial})}} {\memgloref{}}|memjustarg}{441} -\glossaryentry{temp.deduct.type@ {\memgloterm{temp.deduct.type}}{\memglodesc{(\ref {temp.deduct.type})}} {\memgloref{}}|memjustarg}{443} -\glossaryentry{temp.deduct.decl@ {\memgloterm{temp.deduct.decl}}{\memglodesc{(\ref {temp.deduct.decl})}} {\memgloref{}}|memjustarg}{449} -\glossaryentry{temp.over@ {\memgloterm{temp.over}}{\memglodesc{(\ref {temp.over})}} {\memgloref{}}|memjustarg}{449} -\glossaryentry{except@ {\memgloterm{except}}{\memglodesc{(\ref {except})}} {\memgloref{}}|memjustarg}{452} -\glossaryentry{except.pre@ {\memgloterm{except.pre}}{\memglodesc{(\ref {except.pre})}} {\memgloref{}}|memjustarg}{452} -\glossaryentry{except.throw@ {\memgloterm{except.throw}}{\memglodesc{(\ref {except.throw})}} {\memgloref{}}|memjustarg}{453} -\glossaryentry{except.ctor@ {\memgloterm{except.ctor}}{\memglodesc{(\ref {except.ctor})}} {\memgloref{}}|memjustarg}{454} -\glossaryentry{except.handle@ {\memgloterm{except.handle}}{\memglodesc{(\ref {except.handle})}} {\memgloref{}}|memjustarg}{455} -\glossaryentry{except.spec@ {\memgloterm{except.spec}}{\memglodesc{(\ref {except.spec})}} {\memgloref{}}|memjustarg}{457} -\glossaryentry{except.special@ {\memgloterm{except.special}}{\memglodesc{(\ref {except.special})}} {\memgloref{}}|memjustarg}{459} -\glossaryentry{except.special.general@ {\memgloterm{except.special.general}}{\memglodesc{(\ref {except.special.general})}} {\memgloref{}}|memjustarg}{459} -\glossaryentry{except.terminate@ {\memgloterm{except.terminate}}{\memglodesc{(\ref {except.terminate})}} {\memgloref{}}|memjustarg}{459} -\glossaryentry{except.uncaught@ {\memgloterm{except.uncaught}}{\memglodesc{(\ref {except.uncaught})}} {\memgloref{}}|memjustarg}{460} -\glossaryentry{cpp@ {\memgloterm{cpp}}{\memglodesc{(\ref {cpp})}} {\memgloref{}}|memjustarg}{461} -\glossaryentry{cpp.pre@ {\memgloterm{cpp.pre}}{\memglodesc{(\ref {cpp.pre})}} {\memgloref{}}|memjustarg}{461} -\glossaryentry{cpp.cond@ {\memgloterm{cpp.cond}}{\memglodesc{(\ref {cpp.cond})}} {\memgloref{}}|memjustarg}{463} -\glossaryentry{cpp.include@ {\memgloterm{cpp.include}}{\memglodesc{(\ref {cpp.include})}} {\memgloref{}}|memjustarg}{465} -\glossaryentry{cpp.module@ {\memgloterm{cpp.module}}{\memglodesc{(\ref {cpp.module})}} {\memgloref{}}|memjustarg}{466} -\glossaryentry{cpp.import@ {\memgloterm{cpp.import}}{\memglodesc{(\ref {cpp.import})}} {\memgloref{}}|memjustarg}{467} -\glossaryentry{cpp.replace@ {\memgloterm{cpp.replace}}{\memglodesc{(\ref {cpp.replace})}} {\memgloref{}}|memjustarg}{468} -\glossaryentry{cpp.replace.general@ {\memgloterm{cpp.replace.general}}{\memglodesc{(\ref {cpp.replace.general})}} {\memgloref{}}|memjustarg}{468} -\glossaryentry{cpp.subst@ {\memgloterm{cpp.subst}}{\memglodesc{(\ref {cpp.subst})}} {\memgloref{}}|memjustarg}{470} -\glossaryentry{cpp.stringize@ {\memgloterm{cpp.stringize}}{\memglodesc{(\ref {cpp.stringize})}} {\memgloref{}}|memjustarg}{471} -\glossaryentry{cpp.concat@ {\memgloterm{cpp.concat}}{\memglodesc{(\ref {cpp.concat})}} {\memgloref{}}|memjustarg}{471} -\glossaryentry{cpp.rescan@ {\memgloterm{cpp.rescan}}{\memglodesc{(\ref {cpp.rescan})}} {\memgloref{}}|memjustarg}{473} -\glossaryentry{cpp.scope@ {\memgloterm{cpp.scope}}{\memglodesc{(\ref {cpp.scope})}} {\memgloref{}}|memjustarg}{473} -\glossaryentry{cpp.line@ {\memgloterm{cpp.line}}{\memglodesc{(\ref {cpp.line})}} {\memgloref{}}|memjustarg}{473} -\glossaryentry{cpp.error@ {\memgloterm{cpp.error}}{\memglodesc{(\ref {cpp.error})}} {\memgloref{}}|memjustarg}{474} -\glossaryentry{cpp.pragma@ {\memgloterm{cpp.pragma}}{\memglodesc{(\ref {cpp.pragma})}} {\memgloref{}}|memjustarg}{474} -\glossaryentry{cpp.null@ {\memgloterm{cpp.null}}{\memglodesc{(\ref {cpp.null})}} {\memgloref{}}|memjustarg}{474} -\glossaryentry{cpp.predefined@ {\memgloterm{cpp.predefined}}{\memglodesc{(\ref {cpp.predefined})}} {\memgloref{}}|memjustarg}{474} -\glossaryentry{cpp.pragma.op@ {\memgloterm{cpp.pragma.op}}{\memglodesc{(\ref {cpp.pragma.op})}} {\memgloref{}}|memjustarg}{477} -\glossaryentry{library@ {\memgloterm{library}}{\memglodesc{(\ref {library})}} {\memgloref{}}|memjustarg}{478} -\glossaryentry{library.general@ {\memgloterm{library.general}}{\memglodesc{(\ref {library.general})}} {\memgloref{}}|memjustarg}{478} -\glossaryentry{library.c@ {\memgloterm{library.c}}{\memglodesc{(\ref {library.c})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{description@ {\memgloterm{description}}{\memglodesc{(\ref {description})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{description.general@ {\memgloterm{description.general}}{\memglodesc{(\ref {description.general})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{structure@ {\memgloterm{structure}}{\memglodesc{(\ref {structure})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{structure.elements@ {\memgloterm{structure.elements}}{\memglodesc{(\ref {structure.elements})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{structure.summary@ {\memgloterm{structure.summary}}{\memglodesc{(\ref {structure.summary})}} {\memgloref{}}|memjustarg}{479} -\glossaryentry{structure.requirements@ {\memgloterm{structure.requirements}}{\memglodesc{(\ref {structure.requirements})}} {\memgloref{}}|memjustarg}{480} -\glossaryentry{structure.specifications@ {\memgloterm{structure.specifications}}{\memglodesc{(\ref {structure.specifications})}} {\memgloref{}}|memjustarg}{480} -\glossaryentry{structure.see.also@ {\memgloterm{structure.see.also}}{\memglodesc{(\ref {structure.see.also})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{conventions@ {\memgloterm{conventions}}{\memglodesc{(\ref {conventions})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{conventions.general@ {\memgloterm{conventions.general}}{\memglodesc{(\ref {conventions.general})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{expos.only.entity@ {\memgloterm{expos.only.entity}}{\memglodesc{(\ref {expos.only.entity})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{type.descriptions@ {\memgloterm{type.descriptions}}{\memglodesc{(\ref {type.descriptions})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{type.descriptions.general@ {\memgloterm{type.descriptions.general}}{\memglodesc{(\ref {type.descriptions.general})}} {\memgloref{}}|memjustarg}{482} -\glossaryentry{enumerated.types@ {\memgloterm{enumerated.types}}{\memglodesc{(\ref {enumerated.types})}} {\memgloref{}}|memjustarg}{483} -\glossaryentry{bitmask.types@ {\memgloterm{bitmask.types}}{\memglodesc{(\ref {bitmask.types})}} {\memgloref{}}|memjustarg}{483} -\glossaryentry{character.seq@ {\memgloterm{character.seq}}{\memglodesc{(\ref {character.seq})}} {\memgloref{}}|memjustarg}{484} -\glossaryentry{character.seq.general@ {\memgloterm{character.seq.general}}{\memglodesc{(\ref {character.seq.general})}} {\memgloref{}}|memjustarg}{484} -\glossaryentry{byte.strings@ {\memgloterm{byte.strings}}{\memglodesc{(\ref {byte.strings})}} {\memgloref{}}|memjustarg}{484} -\glossaryentry{multibyte.strings@ {\memgloterm{multibyte.strings}}{\memglodesc{(\ref {multibyte.strings})}} {\memgloref{}}|memjustarg}{484} -\glossaryentry{customization.point.object@ {\memgloterm{customization.point.object}}{\memglodesc{(\ref {customization.point.object})}} {\memgloref{}}|memjustarg}{485} -\glossaryentry{functions.within.classes@ {\memgloterm{functions.within.classes}}{\memglodesc{(\ref {functions.within.classes})}} {\memgloref{}}|memjustarg}{485} -\glossaryentry{objects.within.classes@ {\memgloterm{objects.within.classes}}{\memglodesc{(\ref {objects.within.classes})}} {\memgloref{}}|memjustarg}{485} -\glossaryentry{freestanding.item@ {\memgloterm{freestanding.item}}{\memglodesc{(\ref {freestanding.item})}} {\memgloref{}}|memjustarg}{485} -\glossaryentry{requirements@ {\memgloterm{requirements}}{\memglodesc{(\ref {requirements})}} {\memgloref{}}|memjustarg}{486} -\glossaryentry{requirements.general@ {\memgloterm{requirements.general}}{\memglodesc{(\ref {requirements.general})}} {\memgloref{}}|memjustarg}{486} -\glossaryentry{organization@ {\memgloterm{organization}}{\memglodesc{(\ref {organization})}} {\memgloref{}}|memjustarg}{486} -\glossaryentry{organization.general@ {\memgloterm{organization.general}}{\memglodesc{(\ref {organization.general})}} {\memgloref{}}|memjustarg}{486} -\glossaryentry{contents@ {\memgloterm{contents}}{\memglodesc{(\ref {contents})}} {\memgloref{}}|memjustarg}{486} -\glossaryentry{headers@ {\memgloterm{headers}}{\memglodesc{(\ref {headers})}} {\memgloref{}}|memjustarg}{487} -\glossaryentry{std.modules@ {\memgloterm{std.modules}}{\memglodesc{(\ref {std.modules})}} {\memgloref{}}|memjustarg}{488} -\glossaryentry{compliance@ {\memgloterm{compliance}}{\memglodesc{(\ref {compliance})}} {\memgloref{}}|memjustarg}{489} -\glossaryentry{using@ {\memgloterm{using}}{\memglodesc{(\ref {using})}} {\memgloref{}}|memjustarg}{489} -\glossaryentry{using.overview@ {\memgloterm{using.overview}}{\memglodesc{(\ref {using.overview})}} {\memgloref{}}|memjustarg}{489} -\glossaryentry{using.headers@ {\memgloterm{using.headers}}{\memglodesc{(\ref {using.headers})}} {\memgloref{}}|memjustarg}{489} -\glossaryentry{using.linkage@ {\memgloterm{using.linkage}}{\memglodesc{(\ref {using.linkage})}} {\memgloref{}}|memjustarg}{490} -\glossaryentry{utility.requirements@ {\memgloterm{utility.requirements}}{\memglodesc{(\ref {utility.requirements})}} {\memgloref{}}|memjustarg}{490} -\glossaryentry{utility.requirements.general@ {\memgloterm{utility.requirements.general}}{\memglodesc{(\ref {utility.requirements.general})}} {\memgloref{}}|memjustarg}{490} -\glossaryentry{utility.arg.requirements@ {\memgloterm{utility.arg.requirements}}{\memglodesc{(\ref {utility.arg.requirements})}} {\memgloref{}}|memjustarg}{490} -\glossaryentry{swappable.requirements@ {\memgloterm{swappable.requirements}}{\memglodesc{(\ref {swappable.requirements})}} {\memgloref{}}|memjustarg}{492} -\glossaryentry{nullablepointer.requirements@ {\memgloterm{nullablepointer.requirements}}{\memglodesc{(\ref {nullablepointer.requirements})}} {\memgloref{}}|memjustarg}{493} -\glossaryentry{hash.requirements@ {\memgloterm{hash.requirements}}{\memglodesc{(\ref {hash.requirements})}} {\memgloref{}}|memjustarg}{493} -\glossaryentry{allocator.requirements@ {\memgloterm{allocator.requirements}}{\memglodesc{(\ref {allocator.requirements})}} {\memgloref{}}|memjustarg}{494} -\glossaryentry{allocator.requirements.general@ {\memgloterm{allocator.requirements.general}}{\memglodesc{(\ref {allocator.requirements.general})}} {\memgloref{}}|memjustarg}{494} -\glossaryentry{allocator.requirements.completeness@ {\memgloterm{allocator.requirements.completeness}}{\memglodesc{(\ref {allocator.requirements.completeness})}} {\memgloref{}}|memjustarg}{499} -\glossaryentry{constraints@ {\memgloterm{constraints}}{\memglodesc{(\ref {constraints})}} {\memgloref{}}|memjustarg}{499} -\glossaryentry{constraints.overview@ {\memgloterm{constraints.overview}}{\memglodesc{(\ref {constraints.overview})}} {\memgloref{}}|memjustarg}{499} -\glossaryentry{namespace.constraints@ {\memgloterm{namespace.constraints}}{\memglodesc{(\ref {namespace.constraints})}} {\memgloref{}}|memjustarg}{499} -\glossaryentry{namespace.std@ {\memgloterm{namespace.std}}{\memglodesc{(\ref {namespace.std})}} {\memgloref{}}|memjustarg}{499} -\glossaryentry{namespace.posix@ {\memgloterm{namespace.posix}}{\memglodesc{(\ref {namespace.posix})}} {\memgloref{}}|memjustarg}{500} -\glossaryentry{namespace.future@ {\memgloterm{namespace.future}}{\memglodesc{(\ref {namespace.future})}} {\memgloref{}}|memjustarg}{500} -\glossaryentry{reserved.names@ {\memgloterm{reserved.names}}{\memglodesc{(\ref {reserved.names})}} {\memgloref{}}|memjustarg}{500} -\glossaryentry{reserved.names.general@ {\memgloterm{reserved.names.general}}{\memglodesc{(\ref {reserved.names.general})}} {\memgloref{}}|memjustarg}{500} -\glossaryentry{zombie.names@ {\memgloterm{zombie.names}}{\memglodesc{(\ref {zombie.names})}} {\memgloref{}}|memjustarg}{501} -\glossaryentry{macro.names@ {\memgloterm{macro.names}}{\memglodesc{(\ref {macro.names})}} {\memgloref{}}|memjustarg}{502} -\glossaryentry{extern.names@ {\memgloterm{extern.names}}{\memglodesc{(\ref {extern.names})}} {\memgloref{}}|memjustarg}{502} -\glossaryentry{extern.types@ {\memgloterm{extern.types}}{\memglodesc{(\ref {extern.types})}} {\memgloref{}}|memjustarg}{502} -\glossaryentry{usrlit.suffix@ {\memgloterm{usrlit.suffix}}{\memglodesc{(\ref {usrlit.suffix})}} {\memgloref{}}|memjustarg}{502} -\glossaryentry{alt.headers@ {\memgloterm{alt.headers}}{\memglodesc{(\ref {alt.headers})}} {\memgloref{}}|memjustarg}{502} -\glossaryentry{derived.classes@ {\memgloterm{derived.classes}}{\memglodesc{(\ref {derived.classes})}} {\memgloref{}}|memjustarg}{503} -\glossaryentry{replacement.functions@ {\memgloterm{replacement.functions}}{\memglodesc{(\ref {replacement.functions})}} {\memgloref{}}|memjustarg}{503} -\glossaryentry{handler.functions@ {\memgloterm{handler.functions}}{\memglodesc{(\ref {handler.functions})}} {\memgloref{}}|memjustarg}{503} -\glossaryentry{res.on.functions@ {\memgloterm{res.on.functions}}{\memglodesc{(\ref {res.on.functions})}} {\memgloref{}}|memjustarg}{503} -\glossaryentry{res.on.arguments@ {\memgloterm{res.on.arguments}}{\memglodesc{(\ref {res.on.arguments})}} {\memgloref{}}|memjustarg}{504} -\glossaryentry{res.on.objects@ {\memgloterm{res.on.objects}}{\memglodesc{(\ref {res.on.objects})}} {\memgloref{}}|memjustarg}{504} -\glossaryentry{res.on.requirements@ {\memgloterm{res.on.requirements}}{\memglodesc{(\ref {res.on.requirements})}} {\memgloref{}}|memjustarg}{504} -\glossaryentry{conforming@ {\memgloterm{conforming}}{\memglodesc{(\ref {conforming})}} {\memgloref{}}|memjustarg}{504} -\glossaryentry{conforming.overview@ {\memgloterm{conforming.overview}}{\memglodesc{(\ref {conforming.overview})}} {\memgloref{}}|memjustarg}{504} -\glossaryentry{res.on.headers@ {\memgloterm{res.on.headers}}{\memglodesc{(\ref {res.on.headers})}} {\memgloref{}}|memjustarg}{505} -\glossaryentry{res.on.macro.definitions@ {\memgloterm{res.on.macro.definitions}}{\memglodesc{(\ref {res.on.macro.definitions})}} {\memgloref{}}|memjustarg}{505} -\glossaryentry{global.functions@ {\memgloterm{global.functions}}{\memglodesc{(\ref {global.functions})}} {\memgloref{}}|memjustarg}{505} -\glossaryentry{member.functions@ {\memgloterm{member.functions}}{\memglodesc{(\ref {member.functions})}} {\memgloref{}}|memjustarg}{505} -\glossaryentry{hidden.friends@ {\memgloterm{hidden.friends}}{\memglodesc{(\ref {hidden.friends})}} {\memgloref{}}|memjustarg}{505} -\glossaryentry{constexpr.functions@ {\memgloterm{constexpr.functions}}{\memglodesc{(\ref {constexpr.functions})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{algorithm.stable@ {\memgloterm{algorithm.stable}}{\memglodesc{(\ref {algorithm.stable})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{reentrancy@ {\memgloterm{reentrancy}}{\memglodesc{(\ref {reentrancy})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{res.on.data.races@ {\memgloterm{res.on.data.races}}{\memglodesc{(\ref {res.on.data.races})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{protection.within.classes@ {\memgloterm{protection.within.classes}}{\memglodesc{(\ref {protection.within.classes})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{derivation@ {\memgloterm{derivation}}{\memglodesc{(\ref {derivation})}} {\memgloref{}}|memjustarg}{506} -\glossaryentry{res.on.exception.handling@ {\memgloterm{res.on.exception.handling}}{\memglodesc{(\ref {res.on.exception.handling})}} {\memgloref{}}|memjustarg}{507} -\glossaryentry{value.error.codes@ {\memgloterm{value.error.codes}}{\memglodesc{(\ref {value.error.codes})}} {\memgloref{}}|memjustarg}{507} -\glossaryentry{lib.types.movedfrom@ {\memgloterm{lib.types.movedfrom}}{\memglodesc{(\ref {lib.types.movedfrom})}} {\memgloref{}}|memjustarg}{507} -\glossaryentry{support@ {\memgloterm{support}}{\memglodesc{(\ref {support})}} {\memgloref{}}|memjustarg}{508} -\glossaryentry{support.general@ {\memgloterm{support.general}}{\memglodesc{(\ref {support.general})}} {\memgloref{}}|memjustarg}{508} -\glossaryentry{support.types@ {\memgloterm{support.types}}{\memglodesc{(\ref {support.types})}} {\memgloref{}}|memjustarg}{508} -\glossaryentry{cstddef.syn@ {\memgloterm{cstddef.syn}}{\memglodesc{(\ref {cstddef.syn})}} {\memgloref{}}|memjustarg}{508} -\glossaryentry{cstdlib.syn@ {\memgloterm{cstdlib.syn}}{\memglodesc{(\ref {cstdlib.syn})}} {\memgloref{}}|memjustarg}{509} -\glossaryentry{support.types.nullptr@ {\memgloterm{support.types.nullptr}}{\memglodesc{(\ref {support.types.nullptr})}} {\memgloref{}}|memjustarg}{510} -\glossaryentry{support.types.layout@ {\memgloterm{support.types.layout}}{\memglodesc{(\ref {support.types.layout})}} {\memgloref{}}|memjustarg}{510} -\glossaryentry{support.types.byteops@ {\memgloterm{support.types.byteops}}{\memglodesc{(\ref {support.types.byteops})}} {\memgloref{}}|memjustarg}{511} -\glossaryentry{support.limits@ {\memgloterm{support.limits}}{\memglodesc{(\ref {support.limits})}} {\memgloref{}}|memjustarg}{512} -\glossaryentry{support.limits.general@ {\memgloterm{support.limits.general}}{\memglodesc{(\ref {support.limits.general})}} {\memgloref{}}|memjustarg}{512} -\glossaryentry{version.syn@ {\memgloterm{version.syn}}{\memglodesc{(\ref {version.syn})}} {\memgloref{}}|memjustarg}{512} -\glossaryentry{limits.syn@ {\memgloterm{limits.syn}}{\memglodesc{(\ref {limits.syn})}} {\memgloref{}}|memjustarg}{515} -\glossaryentry{round.style@ {\memgloterm{round.style}}{\memglodesc{(\ref {round.style})}} {\memgloref{}}|memjustarg}{516} -\glossaryentry{numeric.limits@ {\memgloterm{numeric.limits}}{\memglodesc{(\ref {numeric.limits})}} {\memgloref{}}|memjustarg}{516} -\glossaryentry{numeric.limits.general@ {\memgloterm{numeric.limits.general}}{\memglodesc{(\ref {numeric.limits.general})}} {\memgloref{}}|memjustarg}{516} -\glossaryentry{numeric.limits.members@ {\memgloterm{numeric.limits.members}}{\memglodesc{(\ref {numeric.limits.members})}} {\memgloref{}}|memjustarg}{517} -\glossaryentry{numeric.special@ {\memgloterm{numeric.special}}{\memglodesc{(\ref {numeric.special})}} {\memgloref{}}|memjustarg}{520} -\glossaryentry{climits.syn@ {\memgloterm{climits.syn}}{\memglodesc{(\ref {climits.syn})}} {\memgloref{}}|memjustarg}{522} -\glossaryentry{cfloat.syn@ {\memgloterm{cfloat.syn}}{\memglodesc{(\ref {cfloat.syn})}} {\memgloref{}}|memjustarg}{522} -\glossaryentry{support.arith.types@ {\memgloterm{support.arith.types}}{\memglodesc{(\ref {support.arith.types})}} {\memgloref{}}|memjustarg}{523} -\glossaryentry{cstdint.syn@ {\memgloterm{cstdint.syn}}{\memglodesc{(\ref {cstdint.syn})}} {\memgloref{}}|memjustarg}{523} -\glossaryentry{stdfloat.syn@ {\memgloterm{stdfloat.syn}}{\memglodesc{(\ref {stdfloat.syn})}} {\memgloref{}}|memjustarg}{524} -\glossaryentry{support.start.term@ {\memgloterm{support.start.term}}{\memglodesc{(\ref {support.start.term})}} {\memgloref{}}|memjustarg}{525} -\glossaryentry{support.dynamic@ {\memgloterm{support.dynamic}}{\memglodesc{(\ref {support.dynamic})}} {\memgloref{}}|memjustarg}{526} -\glossaryentry{support.dynamic.general@ {\memgloterm{support.dynamic.general}}{\memglodesc{(\ref {support.dynamic.general})}} {\memgloref{}}|memjustarg}{526} -\glossaryentry{new.syn@ {\memgloterm{new.syn}}{\memglodesc{(\ref {new.syn})}} {\memgloref{}}|memjustarg}{526} -\glossaryentry{new.delete@ {\memgloterm{new.delete}}{\memglodesc{(\ref {new.delete})}} {\memgloref{}}|memjustarg}{527} -\glossaryentry{new.delete.general@ {\memgloterm{new.delete.general}}{\memglodesc{(\ref {new.delete.general})}} {\memgloref{}}|memjustarg}{527} -\glossaryentry{new.delete.single@ {\memgloterm{new.delete.single}}{\memglodesc{(\ref {new.delete.single})}} {\memgloref{}}|memjustarg}{527} -\glossaryentry{new.delete.array@ {\memgloterm{new.delete.array}}{\memglodesc{(\ref {new.delete.array})}} {\memgloref{}}|memjustarg}{529} -\glossaryentry{new.delete.placement@ {\memgloterm{new.delete.placement}}{\memglodesc{(\ref {new.delete.placement})}} {\memgloref{}}|memjustarg}{530} -\glossaryentry{new.delete.dataraces@ {\memgloterm{new.delete.dataraces}}{\memglodesc{(\ref {new.delete.dataraces})}} {\memgloref{}}|memjustarg}{531} -\glossaryentry{alloc.errors@ {\memgloterm{alloc.errors}}{\memglodesc{(\ref {alloc.errors})}} {\memgloref{}}|memjustarg}{531} -\glossaryentry{bad.alloc@ {\memgloterm{bad.alloc}}{\memglodesc{(\ref {bad.alloc})}} {\memgloref{}}|memjustarg}{531} -\glossaryentry{new.badlength@ {\memgloterm{new.badlength}}{\memglodesc{(\ref {new.badlength})}} {\memgloref{}}|memjustarg}{531} -\glossaryentry{new.handler@ {\memgloterm{new.handler}}{\memglodesc{(\ref {new.handler})}} {\memgloref{}}|memjustarg}{531} -\glossaryentry{set.new.handler@ {\memgloterm{set.new.handler}}{\memglodesc{(\ref {set.new.handler})}} {\memgloref{}}|memjustarg}{532} -\glossaryentry{get.new.handler@ {\memgloterm{get.new.handler}}{\memglodesc{(\ref {get.new.handler})}} {\memgloref{}}|memjustarg}{532} -\glossaryentry{ptr.launder@ {\memgloterm{ptr.launder}}{\memglodesc{(\ref {ptr.launder})}} {\memgloref{}}|memjustarg}{532} -\glossaryentry{hardware.interference@ {\memgloterm{hardware.interference}}{\memglodesc{(\ref {hardware.interference})}} {\memgloref{}}|memjustarg}{532} -\glossaryentry{support.rtti@ {\memgloterm{support.rtti}}{\memglodesc{(\ref {support.rtti})}} {\memgloref{}}|memjustarg}{533} -\glossaryentry{support.rtti.general@ {\memgloterm{support.rtti.general}}{\memglodesc{(\ref {support.rtti.general})}} {\memgloref{}}|memjustarg}{533} -\glossaryentry{typeinfo.syn@ {\memgloterm{typeinfo.syn}}{\memglodesc{(\ref {typeinfo.syn})}} {\memgloref{}}|memjustarg}{533} -\glossaryentry{type.info@ {\memgloterm{type.info}}{\memglodesc{(\ref {type.info})}} {\memgloref{}}|memjustarg}{533} -\glossaryentry{bad.cast@ {\memgloterm{bad.cast}}{\memglodesc{(\ref {bad.cast})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{bad.typeid@ {\memgloterm{bad.typeid}}{\memglodesc{(\ref {bad.typeid})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{support.srcloc@ {\memgloterm{support.srcloc}}{\memglodesc{(\ref {support.srcloc})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{source.location.syn@ {\memgloterm{source.location.syn}}{\memglodesc{(\ref {source.location.syn})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{support.srcloc.class@ {\memgloterm{support.srcloc.class}}{\memglodesc{(\ref {support.srcloc.class})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{support.srcloc.class.general@ {\memgloterm{support.srcloc.class.general}}{\memglodesc{(\ref {support.srcloc.class.general})}} {\memgloref{}}|memjustarg}{534} -\glossaryentry{support.srcloc.cons@ {\memgloterm{support.srcloc.cons}}{\memglodesc{(\ref {support.srcloc.cons})}} {\memgloref{}}|memjustarg}{535} -\glossaryentry{support.srcloc.obs@ {\memgloterm{support.srcloc.obs}}{\memglodesc{(\ref {support.srcloc.obs})}} {\memgloref{}}|memjustarg}{536} -\glossaryentry{support.exception@ {\memgloterm{support.exception}}{\memglodesc{(\ref {support.exception})}} {\memgloref{}}|memjustarg}{536} -\glossaryentry{support.exception.general@ {\memgloterm{support.exception.general}}{\memglodesc{(\ref {support.exception.general})}} {\memgloref{}}|memjustarg}{536} -\glossaryentry{exception.syn@ {\memgloterm{exception.syn}}{\memglodesc{(\ref {exception.syn})}} {\memgloref{}}|memjustarg}{537} -\glossaryentry{exception@ {\memgloterm{exception}}{\memglodesc{(\ref {exception})}} {\memgloref{}}|memjustarg}{537} -\glossaryentry{bad.exception@ {\memgloterm{bad.exception}}{\memglodesc{(\ref {bad.exception})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{exception.terminate@ {\memgloterm{exception.terminate}}{\memglodesc{(\ref {exception.terminate})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{terminate.handler@ {\memgloterm{terminate.handler}}{\memglodesc{(\ref {terminate.handler})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{set.terminate@ {\memgloterm{set.terminate}}{\memglodesc{(\ref {set.terminate})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{get.terminate@ {\memgloterm{get.terminate}}{\memglodesc{(\ref {get.terminate})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{terminate@ {\memgloterm{terminate}}{\memglodesc{(\ref {terminate})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{uncaught.exceptions@ {\memgloterm{uncaught.exceptions}}{\memglodesc{(\ref {uncaught.exceptions})}} {\memgloref{}}|memjustarg}{538} -\glossaryentry{propagation@ {\memgloterm{propagation}}{\memglodesc{(\ref {propagation})}} {\memgloref{}}|memjustarg}{539} -\glossaryentry{except.nested@ {\memgloterm{except.nested}}{\memglodesc{(\ref {except.nested})}} {\memgloref{}}|memjustarg}{539} -\glossaryentry{support.initlist@ {\memgloterm{support.initlist}}{\memglodesc{(\ref {support.initlist})}} {\memgloref{}}|memjustarg}{540} -\glossaryentry{support.initlist.general@ {\memgloterm{support.initlist.general}}{\memglodesc{(\ref {support.initlist.general})}} {\memgloref{}}|memjustarg}{540} -\glossaryentry{initializer.list.syn@ {\memgloterm{initializer.list.syn}}{\memglodesc{(\ref {initializer.list.syn})}} {\memgloref{}}|memjustarg}{540} -\glossaryentry{support.initlist.cons@ {\memgloterm{support.initlist.cons}}{\memglodesc{(\ref {support.initlist.cons})}} {\memgloref{}}|memjustarg}{541} -\glossaryentry{support.initlist.access@ {\memgloterm{support.initlist.access}}{\memglodesc{(\ref {support.initlist.access})}} {\memgloref{}}|memjustarg}{541} -\glossaryentry{support.initlist.range@ {\memgloterm{support.initlist.range}}{\memglodesc{(\ref {support.initlist.range})}} {\memgloref{}}|memjustarg}{541} -\glossaryentry{cmp@ {\memgloterm{cmp}}{\memglodesc{(\ref {cmp})}} {\memgloref{}}|memjustarg}{541} -\glossaryentry{compare.syn@ {\memgloterm{compare.syn}}{\memglodesc{(\ref {compare.syn})}} {\memgloref{}}|memjustarg}{541} -\glossaryentry{cmp.categories@ {\memgloterm{cmp.categories}}{\memglodesc{(\ref {cmp.categories})}} {\memgloref{}}|memjustarg}{542} -\glossaryentry{cmp.categories.pre@ {\memgloterm{cmp.categories.pre}}{\memglodesc{(\ref {cmp.categories.pre})}} {\memgloref{}}|memjustarg}{542} -\glossaryentry{cmp.partialord@ {\memgloterm{cmp.partialord}}{\memglodesc{(\ref {cmp.partialord})}} {\memgloref{}}|memjustarg}{542} -\glossaryentry{cmp.weakord@ {\memgloterm{cmp.weakord}}{\memglodesc{(\ref {cmp.weakord})}} {\memgloref{}}|memjustarg}{544} -\glossaryentry{cmp.strongord@ {\memgloterm{cmp.strongord}}{\memglodesc{(\ref {cmp.strongord})}} {\memgloref{}}|memjustarg}{545} -\glossaryentry{cmp.common@ {\memgloterm{cmp.common}}{\memglodesc{(\ref {cmp.common})}} {\memgloref{}}|memjustarg}{546} -\glossaryentry{cmp.concept@ {\memgloterm{cmp.concept}}{\memglodesc{(\ref {cmp.concept})}} {\memgloref{}}|memjustarg}{546} -\glossaryentry{cmp.result@ {\memgloterm{cmp.result}}{\memglodesc{(\ref {cmp.result})}} {\memgloref{}}|memjustarg}{547} -\glossaryentry{cmp.alg@ {\memgloterm{cmp.alg}}{\memglodesc{(\ref {cmp.alg})}} {\memgloref{}}|memjustarg}{548} -\glossaryentry{support.coroutine@ {\memgloterm{support.coroutine}}{\memglodesc{(\ref {support.coroutine})}} {\memgloref{}}|memjustarg}{549} -\glossaryentry{support.coroutine.general@ {\memgloterm{support.coroutine.general}}{\memglodesc{(\ref {support.coroutine.general})}} {\memgloref{}}|memjustarg}{549} -\glossaryentry{coroutine.syn@ {\memgloterm{coroutine.syn}}{\memglodesc{(\ref {coroutine.syn})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.traits@ {\memgloterm{coroutine.traits}}{\memglodesc{(\ref {coroutine.traits})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.traits.general@ {\memgloterm{coroutine.traits.general}}{\memglodesc{(\ref {coroutine.traits.general})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.traits.primary@ {\memgloterm{coroutine.traits.primary}}{\memglodesc{(\ref {coroutine.traits.primary})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.handle@ {\memgloterm{coroutine.handle}}{\memglodesc{(\ref {coroutine.handle})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.handle.general@ {\memgloterm{coroutine.handle.general}}{\memglodesc{(\ref {coroutine.handle.general})}} {\memgloref{}}|memjustarg}{550} -\glossaryentry{coroutine.handle.con@ {\memgloterm{coroutine.handle.con}}{\memglodesc{(\ref {coroutine.handle.con})}} {\memgloref{}}|memjustarg}{551} -\glossaryentry{coroutine.handle.conv@ {\memgloterm{coroutine.handle.conv}}{\memglodesc{(\ref {coroutine.handle.conv})}} {\memgloref{}}|memjustarg}{552} -\glossaryentry{coroutine.handle.export.import@ {\memgloterm{coroutine.handle.export.import}}{\memglodesc{(\ref {coroutine.handle.export.import})}} {\memgloref{}}|memjustarg}{552} -\glossaryentry{coroutine.handle.observers@ {\memgloterm{coroutine.handle.observers}}{\memglodesc{(\ref {coroutine.handle.observers})}} {\memgloref{}}|memjustarg}{552} -\glossaryentry{coroutine.handle.resumption@ {\memgloterm{coroutine.handle.resumption}}{\memglodesc{(\ref {coroutine.handle.resumption})}} {\memgloref{}}|memjustarg}{552} -\glossaryentry{coroutine.handle.promise@ {\memgloterm{coroutine.handle.promise}}{\memglodesc{(\ref {coroutine.handle.promise})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.handle.compare@ {\memgloterm{coroutine.handle.compare}}{\memglodesc{(\ref {coroutine.handle.compare})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.handle.hash@ {\memgloterm{coroutine.handle.hash}}{\memglodesc{(\ref {coroutine.handle.hash})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.noop@ {\memgloterm{coroutine.noop}}{\memglodesc{(\ref {coroutine.noop})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.promise.noop@ {\memgloterm{coroutine.promise.noop}}{\memglodesc{(\ref {coroutine.promise.noop})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.handle.noop@ {\memgloterm{coroutine.handle.noop}}{\memglodesc{(\ref {coroutine.handle.noop})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.handle.noop.conv@ {\memgloterm{coroutine.handle.noop.conv}}{\memglodesc{(\ref {coroutine.handle.noop.conv})}} {\memgloref{}}|memjustarg}{553} -\glossaryentry{coroutine.handle.noop.observers@ {\memgloterm{coroutine.handle.noop.observers}}{\memglodesc{(\ref {coroutine.handle.noop.observers})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{coroutine.handle.noop.resumption@ {\memgloterm{coroutine.handle.noop.resumption}}{\memglodesc{(\ref {coroutine.handle.noop.resumption})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{coroutine.handle.noop.promise@ {\memgloterm{coroutine.handle.noop.promise}}{\memglodesc{(\ref {coroutine.handle.noop.promise})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{coroutine.handle.noop.address@ {\memgloterm{coroutine.handle.noop.address}}{\memglodesc{(\ref {coroutine.handle.noop.address})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{coroutine.noop.coroutine@ {\memgloterm{coroutine.noop.coroutine}}{\memglodesc{(\ref {coroutine.noop.coroutine})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{coroutine.trivial.awaitables@ {\memgloterm{coroutine.trivial.awaitables}}{\memglodesc{(\ref {coroutine.trivial.awaitables})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{support.runtime@ {\memgloterm{support.runtime}}{\memglodesc{(\ref {support.runtime})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{support.runtime.general@ {\memgloterm{support.runtime.general}}{\memglodesc{(\ref {support.runtime.general})}} {\memgloref{}}|memjustarg}{554} -\glossaryentry{cstdarg.syn@ {\memgloterm{cstdarg.syn}}{\memglodesc{(\ref {cstdarg.syn})}} {\memgloref{}}|memjustarg}{555} -\glossaryentry{csetjmp.syn@ {\memgloterm{csetjmp.syn}}{\memglodesc{(\ref {csetjmp.syn})}} {\memgloref{}}|memjustarg}{555} -\glossaryentry{csignal.syn@ {\memgloterm{csignal.syn}}{\memglodesc{(\ref {csignal.syn})}} {\memgloref{}}|memjustarg}{555} -\glossaryentry{support.signal@ {\memgloterm{support.signal}}{\memglodesc{(\ref {support.signal})}} {\memgloref{}}|memjustarg}{556} -\glossaryentry{support.c.headers@ {\memgloterm{support.c.headers}}{\memglodesc{(\ref {support.c.headers})}} {\memgloref{}}|memjustarg}{556} -\glossaryentry{support.c.headers.general@ {\memgloterm{support.c.headers.general}}{\memglodesc{(\ref {support.c.headers.general})}} {\memgloref{}}|memjustarg}{556} -\glossaryentry{complex.h.syn@ {\memgloterm{complex.h.syn}}{\memglodesc{(\ref {complex.h.syn})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{iso646.h.syn@ {\memgloterm{iso646.h.syn}}{\memglodesc{(\ref {iso646.h.syn})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{stdalign.h.syn@ {\memgloterm{stdalign.h.syn}}{\memglodesc{(\ref {stdalign.h.syn})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{stdbool.h.syn@ {\memgloterm{stdbool.h.syn}}{\memglodesc{(\ref {stdbool.h.syn})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{tgmath.h.syn@ {\memgloterm{tgmath.h.syn}}{\memglodesc{(\ref {tgmath.h.syn})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{support.c.headers.other@ {\memgloterm{support.c.headers.other}}{\memglodesc{(\ref {support.c.headers.other})}} {\memgloref{}}|memjustarg}{557} -\glossaryentry{concepts@ {\memgloterm{concepts}}{\memglodesc{(\ref {concepts})}} {\memgloref{}}|memjustarg}{559} -\glossaryentry{concepts.general@ {\memgloterm{concepts.general}}{\memglodesc{(\ref {concepts.general})}} {\memgloref{}}|memjustarg}{559} -\glossaryentry{concepts.equality@ {\memgloterm{concepts.equality}}{\memglodesc{(\ref {concepts.equality})}} {\memgloref{}}|memjustarg}{559} -\glossaryentry{concepts.syn@ {\memgloterm{concepts.syn}}{\memglodesc{(\ref {concepts.syn})}} {\memgloref{}}|memjustarg}{560} -\glossaryentry{concepts.lang@ {\memgloterm{concepts.lang}}{\memglodesc{(\ref {concepts.lang})}} {\memgloref{}}|memjustarg}{562} -\glossaryentry{concepts.lang.general@ {\memgloterm{concepts.lang.general}}{\memglodesc{(\ref {concepts.lang.general})}} {\memgloref{}}|memjustarg}{562} -\glossaryentry{concept.same@ {\memgloterm{concept.same}}{\memglodesc{(\ref {concept.same})}} {\memgloref{}}|memjustarg}{562} -\glossaryentry{concept.derived@ {\memgloterm{concept.derived}}{\memglodesc{(\ref {concept.derived})}} {\memgloref{}}|memjustarg}{562} -\glossaryentry{concept.convertible@ {\memgloterm{concept.convertible}}{\memglodesc{(\ref {concept.convertible})}} {\memgloref{}}|memjustarg}{563} -\glossaryentry{concept.commonref@ {\memgloterm{concept.commonref}}{\memglodesc{(\ref {concept.commonref})}} {\memgloref{}}|memjustarg}{563} -\glossaryentry{concept.common@ {\memgloterm{concept.common}}{\memglodesc{(\ref {concept.common})}} {\memgloref{}}|memjustarg}{563} -\glossaryentry{concepts.arithmetic@ {\memgloterm{concepts.arithmetic}}{\memglodesc{(\ref {concepts.arithmetic})}} {\memgloref{}}|memjustarg}{564} -\glossaryentry{concept.assignable@ {\memgloterm{concept.assignable}}{\memglodesc{(\ref {concept.assignable})}} {\memgloref{}}|memjustarg}{564} -\glossaryentry{concept.swappable@ {\memgloterm{concept.swappable}}{\memglodesc{(\ref {concept.swappable})}} {\memgloref{}}|memjustarg}{565} -\glossaryentry{concept.destructible@ {\memgloterm{concept.destructible}}{\memglodesc{(\ref {concept.destructible})}} {\memgloref{}}|memjustarg}{566} -\glossaryentry{concept.constructible@ {\memgloterm{concept.constructible}}{\memglodesc{(\ref {concept.constructible})}} {\memgloref{}}|memjustarg}{566} -\glossaryentry{concept.default.init@ {\memgloterm{concept.default.init}}{\memglodesc{(\ref {concept.default.init})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concept.moveconstructible@ {\memgloterm{concept.moveconstructible}}{\memglodesc{(\ref {concept.moveconstructible})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concept.copyconstructible@ {\memgloterm{concept.copyconstructible}}{\memglodesc{(\ref {concept.copyconstructible})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concepts.compare@ {\memgloterm{concepts.compare}}{\memglodesc{(\ref {concepts.compare})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concepts.compare.general@ {\memgloterm{concepts.compare.general}}{\memglodesc{(\ref {concepts.compare.general})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concept.booleantestable@ {\memgloterm{concept.booleantestable}}{\memglodesc{(\ref {concept.booleantestable})}} {\memgloref{}}|memjustarg}{567} -\glossaryentry{concept.comparisoncommontype@ {\memgloterm{concept.comparisoncommontype}}{\memglodesc{(\ref {concept.comparisoncommontype})}} {\memgloref{}}|memjustarg}{568} -\glossaryentry{concept.equalitycomparable@ {\memgloterm{concept.equalitycomparable}}{\memglodesc{(\ref {concept.equalitycomparable})}} {\memgloref{}}|memjustarg}{569} -\glossaryentry{concept.totallyordered@ {\memgloterm{concept.totallyordered}}{\memglodesc{(\ref {concept.totallyordered})}} {\memgloref{}}|memjustarg}{569} -\glossaryentry{concepts.object@ {\memgloterm{concepts.object}}{\memglodesc{(\ref {concepts.object})}} {\memgloref{}}|memjustarg}{570} -\glossaryentry{concepts.callable@ {\memgloterm{concepts.callable}}{\memglodesc{(\ref {concepts.callable})}} {\memgloref{}}|memjustarg}{570} -\glossaryentry{concepts.callable.general@ {\memgloterm{concepts.callable.general}}{\memglodesc{(\ref {concepts.callable.general})}} {\memgloref{}}|memjustarg}{570} -\glossaryentry{concept.invocable@ {\memgloterm{concept.invocable}}{\memglodesc{(\ref {concept.invocable})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{concept.regularinvocable@ {\memgloterm{concept.regularinvocable}}{\memglodesc{(\ref {concept.regularinvocable})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{concept.predicate@ {\memgloterm{concept.predicate}}{\memglodesc{(\ref {concept.predicate})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{concept.relation@ {\memgloterm{concept.relation}}{\memglodesc{(\ref {concept.relation})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{concept.equiv@ {\memgloterm{concept.equiv}}{\memglodesc{(\ref {concept.equiv})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{concept.strictweakorder@ {\memgloterm{concept.strictweakorder}}{\memglodesc{(\ref {concept.strictweakorder})}} {\memgloref{}}|memjustarg}{571} -\glossaryentry{diagnostics@ {\memgloterm{diagnostics}}{\memglodesc{(\ref {diagnostics})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{diagnostics.general@ {\memgloterm{diagnostics.general}}{\memglodesc{(\ref {diagnostics.general})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{std.exceptions@ {\memgloterm{std.exceptions}}{\memglodesc{(\ref {std.exceptions})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{std.exceptions.general@ {\memgloterm{std.exceptions.general}}{\memglodesc{(\ref {std.exceptions.general})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{stdexcept.syn@ {\memgloterm{stdexcept.syn}}{\memglodesc{(\ref {stdexcept.syn})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{logic.error@ {\memgloterm{logic.error}}{\memglodesc{(\ref {logic.error})}} {\memgloref{}}|memjustarg}{572} -\glossaryentry{domain.error@ {\memgloterm{domain.error}}{\memglodesc{(\ref {domain.error})}} {\memgloref{}}|memjustarg}{573} -\glossaryentry{invalid.argument@ {\memgloterm{invalid.argument}}{\memglodesc{(\ref {invalid.argument})}} {\memgloref{}}|memjustarg}{573} -\glossaryentry{length.error@ {\memgloterm{length.error}}{\memglodesc{(\ref {length.error})}} {\memgloref{}}|memjustarg}{573} -\glossaryentry{out.of.range@ {\memgloterm{out.of.range}}{\memglodesc{(\ref {out.of.range})}} {\memgloref{}}|memjustarg}{574} -\glossaryentry{runtime.error@ {\memgloterm{runtime.error}}{\memglodesc{(\ref {runtime.error})}} {\memgloref{}}|memjustarg}{574} -\glossaryentry{range.error@ {\memgloterm{range.error}}{\memglodesc{(\ref {range.error})}} {\memgloref{}}|memjustarg}{574} -\glossaryentry{overflow.error@ {\memgloterm{overflow.error}}{\memglodesc{(\ref {overflow.error})}} {\memgloref{}}|memjustarg}{574} -\glossaryentry{underflow.error@ {\memgloterm{underflow.error}}{\memglodesc{(\ref {underflow.error})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{assertions@ {\memgloterm{assertions}}{\memglodesc{(\ref {assertions})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{assertions.general@ {\memgloterm{assertions.general}}{\memglodesc{(\ref {assertions.general})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{cassert.syn@ {\memgloterm{cassert.syn}}{\memglodesc{(\ref {cassert.syn})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{assertions.assert@ {\memgloterm{assertions.assert}}{\memglodesc{(\ref {assertions.assert})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{errno@ {\memgloterm{errno}}{\memglodesc{(\ref {errno})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{errno.general@ {\memgloterm{errno.general}}{\memglodesc{(\ref {errno.general})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{cerrno.syn@ {\memgloterm{cerrno.syn}}{\memglodesc{(\ref {cerrno.syn})}} {\memgloref{}}|memjustarg}{575} -\glossaryentry{syserr@ {\memgloterm{syserr}}{\memglodesc{(\ref {syserr})}} {\memgloref{}}|memjustarg}{577} -\glossaryentry{syserr.general@ {\memgloterm{syserr.general}}{\memglodesc{(\ref {syserr.general})}} {\memgloref{}}|memjustarg}{577} -\glossaryentry{system.error.syn@ {\memgloterm{system.error.syn}}{\memglodesc{(\ref {system.error.syn})}} {\memgloref{}}|memjustarg}{577} -\glossaryentry{syserr.errcat@ {\memgloterm{syserr.errcat}}{\memglodesc{(\ref {syserr.errcat})}} {\memgloref{}}|memjustarg}{579} -\glossaryentry{syserr.errcat.overview@ {\memgloterm{syserr.errcat.overview}}{\memglodesc{(\ref {syserr.errcat.overview})}} {\memgloref{}}|memjustarg}{579} -\glossaryentry{syserr.errcat.virtuals@ {\memgloterm{syserr.errcat.virtuals}}{\memglodesc{(\ref {syserr.errcat.virtuals})}} {\memgloref{}}|memjustarg}{579} -\glossaryentry{syserr.errcat.nonvirtuals@ {\memgloterm{syserr.errcat.nonvirtuals}}{\memglodesc{(\ref {syserr.errcat.nonvirtuals})}} {\memgloref{}}|memjustarg}{580} -\glossaryentry{syserr.errcat.derived@ {\memgloterm{syserr.errcat.derived}}{\memglodesc{(\ref {syserr.errcat.derived})}} {\memgloref{}}|memjustarg}{580} -\glossaryentry{syserr.errcat.objects@ {\memgloterm{syserr.errcat.objects}}{\memglodesc{(\ref {syserr.errcat.objects})}} {\memgloref{}}|memjustarg}{580} -\glossaryentry{syserr.errcode@ {\memgloterm{syserr.errcode}}{\memglodesc{(\ref {syserr.errcode})}} {\memgloref{}}|memjustarg}{581} -\glossaryentry{syserr.errcode.overview@ {\memgloterm{syserr.errcode.overview}}{\memglodesc{(\ref {syserr.errcode.overview})}} {\memgloref{}}|memjustarg}{581} -\glossaryentry{syserr.errcode.constructors@ {\memgloterm{syserr.errcode.constructors}}{\memglodesc{(\ref {syserr.errcode.constructors})}} {\memgloref{}}|memjustarg}{581} -\glossaryentry{syserr.errcode.modifiers@ {\memgloterm{syserr.errcode.modifiers}}{\memglodesc{(\ref {syserr.errcode.modifiers})}} {\memgloref{}}|memjustarg}{582} -\glossaryentry{syserr.errcode.observers@ {\memgloterm{syserr.errcode.observers}}{\memglodesc{(\ref {syserr.errcode.observers})}} {\memgloref{}}|memjustarg}{582} -\glossaryentry{syserr.errcode.nonmembers@ {\memgloterm{syserr.errcode.nonmembers}}{\memglodesc{(\ref {syserr.errcode.nonmembers})}} {\memgloref{}}|memjustarg}{582} -\glossaryentry{syserr.errcondition@ {\memgloterm{syserr.errcondition}}{\memglodesc{(\ref {syserr.errcondition})}} {\memgloref{}}|memjustarg}{582} -\glossaryentry{syserr.errcondition.overview@ {\memgloterm{syserr.errcondition.overview}}{\memglodesc{(\ref {syserr.errcondition.overview})}} {\memgloref{}}|memjustarg}{582} -\glossaryentry{syserr.errcondition.constructors@ {\memgloterm{syserr.errcondition.constructors}}{\memglodesc{(\ref {syserr.errcondition.constructors})}} {\memgloref{}}|memjustarg}{583} -\glossaryentry{syserr.errcondition.modifiers@ {\memgloterm{syserr.errcondition.modifiers}}{\memglodesc{(\ref {syserr.errcondition.modifiers})}} {\memgloref{}}|memjustarg}{583} -\glossaryentry{syserr.errcondition.observers@ {\memgloterm{syserr.errcondition.observers}}{\memglodesc{(\ref {syserr.errcondition.observers})}} {\memgloref{}}|memjustarg}{583} -\glossaryentry{syserr.errcondition.nonmembers@ {\memgloterm{syserr.errcondition.nonmembers}}{\memglodesc{(\ref {syserr.errcondition.nonmembers})}} {\memgloref{}}|memjustarg}{584} -\glossaryentry{syserr.compare@ {\memgloterm{syserr.compare}}{\memglodesc{(\ref {syserr.compare})}} {\memgloref{}}|memjustarg}{584} -\glossaryentry{syserr.hash@ {\memgloterm{syserr.hash}}{\memglodesc{(\ref {syserr.hash})}} {\memgloref{}}|memjustarg}{584} -\glossaryentry{syserr.syserr@ {\memgloterm{syserr.syserr}}{\memglodesc{(\ref {syserr.syserr})}} {\memgloref{}}|memjustarg}{584} -\glossaryentry{syserr.syserr.overview@ {\memgloterm{syserr.syserr.overview}}{\memglodesc{(\ref {syserr.syserr.overview})}} {\memgloref{}}|memjustarg}{584} -\glossaryentry{syserr.syserr.members@ {\memgloterm{syserr.syserr.members}}{\memglodesc{(\ref {syserr.syserr.members})}} {\memgloref{}}|memjustarg}{585} -\glossaryentry{stacktrace@ {\memgloterm{stacktrace}}{\memglodesc{(\ref {stacktrace})}} {\memgloref{}}|memjustarg}{585} -\glossaryentry{stacktrace.general@ {\memgloterm{stacktrace.general}}{\memglodesc{(\ref {stacktrace.general})}} {\memgloref{}}|memjustarg}{585} -\glossaryentry{stacktrace.syn@ {\memgloterm{stacktrace.syn}}{\memglodesc{(\ref {stacktrace.syn})}} {\memgloref{}}|memjustarg}{585} -\glossaryentry{stacktrace.entry@ {\memgloterm{stacktrace.entry}}{\memglodesc{(\ref {stacktrace.entry})}} {\memgloref{}}|memjustarg}{586} -\glossaryentry{stacktrace.entry.overview@ {\memgloterm{stacktrace.entry.overview}}{\memglodesc{(\ref {stacktrace.entry.overview})}} {\memgloref{}}|memjustarg}{586} -\glossaryentry{stacktrace.entry.cons@ {\memgloterm{stacktrace.entry.cons}}{\memglodesc{(\ref {stacktrace.entry.cons})}} {\memgloref{}}|memjustarg}{586} -\glossaryentry{stacktrace.entry.obs@ {\memgloterm{stacktrace.entry.obs}}{\memglodesc{(\ref {stacktrace.entry.obs})}} {\memgloref{}}|memjustarg}{587} -\glossaryentry{stacktrace.entry.query@ {\memgloterm{stacktrace.entry.query}}{\memglodesc{(\ref {stacktrace.entry.query})}} {\memgloref{}}|memjustarg}{587} -\glossaryentry{stacktrace.entry.cmp@ {\memgloterm{stacktrace.entry.cmp}}{\memglodesc{(\ref {stacktrace.entry.cmp})}} {\memgloref{}}|memjustarg}{587} -\glossaryentry{stacktrace.basic@ {\memgloterm{stacktrace.basic}}{\memglodesc{(\ref {stacktrace.basic})}} {\memgloref{}}|memjustarg}{587} -\glossaryentry{stacktrace.basic.overview@ {\memgloterm{stacktrace.basic.overview}}{\memglodesc{(\ref {stacktrace.basic.overview})}} {\memgloref{}}|memjustarg}{587} -\glossaryentry{stacktrace.basic.cons@ {\memgloterm{stacktrace.basic.cons}}{\memglodesc{(\ref {stacktrace.basic.cons})}} {\memgloref{}}|memjustarg}{588} -\glossaryentry{stacktrace.basic.obs@ {\memgloterm{stacktrace.basic.obs}}{\memglodesc{(\ref {stacktrace.basic.obs})}} {\memgloref{}}|memjustarg}{589} -\glossaryentry{stacktrace.basic.cmp@ {\memgloterm{stacktrace.basic.cmp}}{\memglodesc{(\ref {stacktrace.basic.cmp})}} {\memgloref{}}|memjustarg}{590} -\glossaryentry{stacktrace.basic.mod@ {\memgloterm{stacktrace.basic.mod}}{\memglodesc{(\ref {stacktrace.basic.mod})}} {\memgloref{}}|memjustarg}{590} -\glossaryentry{stacktrace.basic.nonmem@ {\memgloterm{stacktrace.basic.nonmem}}{\memglodesc{(\ref {stacktrace.basic.nonmem})}} {\memgloref{}}|memjustarg}{590} -\glossaryentry{stacktrace.format@ {\memgloterm{stacktrace.format}}{\memglodesc{(\ref {stacktrace.format})}} {\memgloref{}}|memjustarg}{591} -\glossaryentry{stacktrace.basic.hash@ {\memgloterm{stacktrace.basic.hash}}{\memglodesc{(\ref {stacktrace.basic.hash})}} {\memgloref{}}|memjustarg}{591} -\glossaryentry{mem@ {\memgloterm{mem}}{\memglodesc{(\ref {mem})}} {\memgloref{}}|memjustarg}{592} -\glossaryentry{mem.general@ {\memgloterm{mem.general}}{\memglodesc{(\ref {mem.general})}} {\memgloref{}}|memjustarg}{592} -\glossaryentry{memory@ {\memgloterm{memory}}{\memglodesc{(\ref {memory})}} {\memgloref{}}|memjustarg}{592} -\glossaryentry{memory.general@ {\memgloterm{memory.general}}{\memglodesc{(\ref {memory.general})}} {\memgloref{}}|memjustarg}{592} -\glossaryentry{memory.syn@ {\memgloterm{memory.syn}}{\memglodesc{(\ref {memory.syn})}} {\memgloref{}}|memjustarg}{592} -\glossaryentry{pointer.traits@ {\memgloterm{pointer.traits}}{\memglodesc{(\ref {pointer.traits})}} {\memgloref{}}|memjustarg}{600} -\glossaryentry{pointer.traits.general@ {\memgloterm{pointer.traits.general}}{\memglodesc{(\ref {pointer.traits.general})}} {\memgloref{}}|memjustarg}{600} -\glossaryentry{pointer.traits.types@ {\memgloterm{pointer.traits.types}}{\memglodesc{(\ref {pointer.traits.types})}} {\memgloref{}}|memjustarg}{601} -\glossaryentry{pointer.traits.functions@ {\memgloterm{pointer.traits.functions}}{\memglodesc{(\ref {pointer.traits.functions})}} {\memgloref{}}|memjustarg}{601} -\glossaryentry{pointer.traits.optmem@ {\memgloterm{pointer.traits.optmem}}{\memglodesc{(\ref {pointer.traits.optmem})}} {\memgloref{}}|memjustarg}{602} -\glossaryentry{pointer.conversion@ {\memgloterm{pointer.conversion}}{\memglodesc{(\ref {pointer.conversion})}} {\memgloref{}}|memjustarg}{602} -\glossaryentry{ptr.align@ {\memgloterm{ptr.align}}{\memglodesc{(\ref {ptr.align})}} {\memgloref{}}|memjustarg}{602} -\glossaryentry{obj.lifetime@ {\memgloterm{obj.lifetime}}{\memglodesc{(\ref {obj.lifetime})}} {\memgloref{}}|memjustarg}{602} -\glossaryentry{allocator.tag@ {\memgloterm{allocator.tag}}{\memglodesc{(\ref {allocator.tag})}} {\memgloref{}}|memjustarg}{603} -\glossaryentry{allocator.uses@ {\memgloterm{allocator.uses}}{\memglodesc{(\ref {allocator.uses})}} {\memgloref{}}|memjustarg}{603} -\glossaryentry{allocator.uses.trait@ {\memgloterm{allocator.uses.trait}}{\memglodesc{(\ref {allocator.uses.trait})}} {\memgloref{}}|memjustarg}{603} -\glossaryentry{allocator.uses.construction@ {\memgloterm{allocator.uses.construction}}{\memglodesc{(\ref {allocator.uses.construction})}} {\memgloref{}}|memjustarg}{603} -\glossaryentry{allocator.traits@ {\memgloterm{allocator.traits}}{\memglodesc{(\ref {allocator.traits})}} {\memgloref{}}|memjustarg}{606} -\glossaryentry{allocator.traits.general@ {\memgloterm{allocator.traits.general}}{\memglodesc{(\ref {allocator.traits.general})}} {\memgloref{}}|memjustarg}{606} -\glossaryentry{allocator.traits.types@ {\memgloterm{allocator.traits.types}}{\memglodesc{(\ref {allocator.traits.types})}} {\memgloref{}}|memjustarg}{607} -\glossaryentry{allocator.traits.members@ {\memgloterm{allocator.traits.members}}{\memglodesc{(\ref {allocator.traits.members})}} {\memgloref{}}|memjustarg}{608} -\glossaryentry{allocator.traits.other@ {\memgloterm{allocator.traits.other}}{\memglodesc{(\ref {allocator.traits.other})}} {\memgloref{}}|memjustarg}{608} -\glossaryentry{default.allocator@ {\memgloterm{default.allocator}}{\memglodesc{(\ref {default.allocator})}} {\memgloref{}}|memjustarg}{608} -\glossaryentry{default.allocator.general@ {\memgloterm{default.allocator.general}}{\memglodesc{(\ref {default.allocator.general})}} {\memgloref{}}|memjustarg}{608} -\glossaryentry{allocator.members@ {\memgloterm{allocator.members}}{\memglodesc{(\ref {allocator.members})}} {\memgloref{}}|memjustarg}{609} -\glossaryentry{allocator.globals@ {\memgloterm{allocator.globals}}{\memglodesc{(\ref {allocator.globals})}} {\memgloref{}}|memjustarg}{609} -\glossaryentry{specialized.addressof@ {\memgloterm{specialized.addressof}}{\memglodesc{(\ref {specialized.addressof})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{c.malloc@ {\memgloterm{c.malloc}}{\memglodesc{(\ref {c.malloc})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{smartptr@ {\memgloterm{smartptr}}{\memglodesc{(\ref {smartptr})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{unique.ptr@ {\memgloterm{unique.ptr}}{\memglodesc{(\ref {unique.ptr})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{unique.ptr.general@ {\memgloterm{unique.ptr.general}}{\memglodesc{(\ref {unique.ptr.general})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{unique.ptr.dltr@ {\memgloterm{unique.ptr.dltr}}{\memglodesc{(\ref {unique.ptr.dltr})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{unique.ptr.dltr.general@ {\memgloterm{unique.ptr.dltr.general}}{\memglodesc{(\ref {unique.ptr.dltr.general})}} {\memgloref{}}|memjustarg}{610} -\glossaryentry{unique.ptr.dltr.dflt@ {\memgloterm{unique.ptr.dltr.dflt}}{\memglodesc{(\ref {unique.ptr.dltr.dflt})}} {\memgloref{}}|memjustarg}{611} -\glossaryentry{unique.ptr.dltr.dflt1@ {\memgloterm{unique.ptr.dltr.dflt1}}{\memglodesc{(\ref {unique.ptr.dltr.dflt1})}} {\memgloref{}}|memjustarg}{611} -\glossaryentry{unique.ptr.single@ {\memgloterm{unique.ptr.single}}{\memglodesc{(\ref {unique.ptr.single})}} {\memgloref{}}|memjustarg}{611} -\glossaryentry{unique.ptr.single.general@ {\memgloterm{unique.ptr.single.general}}{\memglodesc{(\ref {unique.ptr.single.general})}} {\memgloref{}}|memjustarg}{611} -\glossaryentry{unique.ptr.single.ctor@ {\memgloterm{unique.ptr.single.ctor}}{\memglodesc{(\ref {unique.ptr.single.ctor})}} {\memgloref{}}|memjustarg}{612} -\glossaryentry{unique.ptr.single.dtor@ {\memgloterm{unique.ptr.single.dtor}}{\memglodesc{(\ref {unique.ptr.single.dtor})}} {\memgloref{}}|memjustarg}{613} -\glossaryentry{unique.ptr.single.asgn@ {\memgloterm{unique.ptr.single.asgn}}{\memglodesc{(\ref {unique.ptr.single.asgn})}} {\memgloref{}}|memjustarg}{614} -\glossaryentry{unique.ptr.single.observers@ {\memgloterm{unique.ptr.single.observers}}{\memglodesc{(\ref {unique.ptr.single.observers})}} {\memgloref{}}|memjustarg}{614} -\glossaryentry{unique.ptr.single.modifiers@ {\memgloterm{unique.ptr.single.modifiers}}{\memglodesc{(\ref {unique.ptr.single.modifiers})}} {\memgloref{}}|memjustarg}{615} -\glossaryentry{unique.ptr.runtime@ {\memgloterm{unique.ptr.runtime}}{\memglodesc{(\ref {unique.ptr.runtime})}} {\memgloref{}}|memjustarg}{615} -\glossaryentry{unique.ptr.runtime.general@ {\memgloterm{unique.ptr.runtime.general}}{\memglodesc{(\ref {unique.ptr.runtime.general})}} {\memgloref{}}|memjustarg}{615} -\glossaryentry{unique.ptr.runtime.ctor@ {\memgloterm{unique.ptr.runtime.ctor}}{\memglodesc{(\ref {unique.ptr.runtime.ctor})}} {\memgloref{}}|memjustarg}{616} -\glossaryentry{unique.ptr.runtime.asgn@ {\memgloterm{unique.ptr.runtime.asgn}}{\memglodesc{(\ref {unique.ptr.runtime.asgn})}} {\memgloref{}}|memjustarg}{616} -\glossaryentry{unique.ptr.runtime.observers@ {\memgloterm{unique.ptr.runtime.observers}}{\memglodesc{(\ref {unique.ptr.runtime.observers})}} {\memgloref{}}|memjustarg}{617} -\glossaryentry{unique.ptr.runtime.modifiers@ {\memgloterm{unique.ptr.runtime.modifiers}}{\memglodesc{(\ref {unique.ptr.runtime.modifiers})}} {\memgloref{}}|memjustarg}{617} -\glossaryentry{unique.ptr.create@ {\memgloterm{unique.ptr.create}}{\memglodesc{(\ref {unique.ptr.create})}} {\memgloref{}}|memjustarg}{617} -\glossaryentry{unique.ptr.special@ {\memgloterm{unique.ptr.special}}{\memglodesc{(\ref {unique.ptr.special})}} {\memgloref{}}|memjustarg}{617} -\glossaryentry{unique.ptr.io@ {\memgloterm{unique.ptr.io}}{\memglodesc{(\ref {unique.ptr.io})}} {\memgloref{}}|memjustarg}{619} -\glossaryentry{util.sharedptr@ {\memgloterm{util.sharedptr}}{\memglodesc{(\ref {util.sharedptr})}} {\memgloref{}}|memjustarg}{619} -\glossaryentry{util.smartptr.weak.bad@ {\memgloterm{util.smartptr.weak.bad}}{\memglodesc{(\ref {util.smartptr.weak.bad})}} {\memgloref{}}|memjustarg}{619} -\glossaryentry{util.smartptr.shared@ {\memgloterm{util.smartptr.shared}}{\memglodesc{(\ref {util.smartptr.shared})}} {\memgloref{}}|memjustarg}{619} -\glossaryentry{util.smartptr.shared.general@ {\memgloterm{util.smartptr.shared.general}}{\memglodesc{(\ref {util.smartptr.shared.general})}} {\memgloref{}}|memjustarg}{619} -\glossaryentry{util.smartptr.shared.const@ {\memgloterm{util.smartptr.shared.const}}{\memglodesc{(\ref {util.smartptr.shared.const})}} {\memgloref{}}|memjustarg}{621} -\glossaryentry{util.smartptr.shared.dest@ {\memgloterm{util.smartptr.shared.dest}}{\memglodesc{(\ref {util.smartptr.shared.dest})}} {\memgloref{}}|memjustarg}{623} -\glossaryentry{util.smartptr.shared.assign@ {\memgloterm{util.smartptr.shared.assign}}{\memglodesc{(\ref {util.smartptr.shared.assign})}} {\memgloref{}}|memjustarg}{623} -\glossaryentry{util.smartptr.shared.mod@ {\memgloterm{util.smartptr.shared.mod}}{\memglodesc{(\ref {util.smartptr.shared.mod})}} {\memgloref{}}|memjustarg}{623} -\glossaryentry{util.smartptr.shared.obs@ {\memgloterm{util.smartptr.shared.obs}}{\memglodesc{(\ref {util.smartptr.shared.obs})}} {\memgloref{}}|memjustarg}{624} -\glossaryentry{util.smartptr.shared.create@ {\memgloterm{util.smartptr.shared.create}}{\memglodesc{(\ref {util.smartptr.shared.create})}} {\memgloref{}}|memjustarg}{624} -\glossaryentry{util.smartptr.shared.cmp@ {\memgloterm{util.smartptr.shared.cmp}}{\memglodesc{(\ref {util.smartptr.shared.cmp})}} {\memgloref{}}|memjustarg}{627} -\glossaryentry{util.smartptr.shared.spec@ {\memgloterm{util.smartptr.shared.spec}}{\memglodesc{(\ref {util.smartptr.shared.spec})}} {\memgloref{}}|memjustarg}{628} -\glossaryentry{util.smartptr.shared.cast@ {\memgloterm{util.smartptr.shared.cast}}{\memglodesc{(\ref {util.smartptr.shared.cast})}} {\memgloref{}}|memjustarg}{628} -\glossaryentry{util.smartptr.getdeleter@ {\memgloterm{util.smartptr.getdeleter}}{\memglodesc{(\ref {util.smartptr.getdeleter})}} {\memgloref{}}|memjustarg}{629} -\glossaryentry{util.smartptr.shared.io@ {\memgloterm{util.smartptr.shared.io}}{\memglodesc{(\ref {util.smartptr.shared.io})}} {\memgloref{}}|memjustarg}{629} -\glossaryentry{util.smartptr.weak@ {\memgloterm{util.smartptr.weak}}{\memglodesc{(\ref {util.smartptr.weak})}} {\memgloref{}}|memjustarg}{629} -\glossaryentry{util.smartptr.weak.general@ {\memgloterm{util.smartptr.weak.general}}{\memglodesc{(\ref {util.smartptr.weak.general})}} {\memgloref{}}|memjustarg}{629} -\glossaryentry{util.smartptr.weak.const@ {\memgloterm{util.smartptr.weak.const}}{\memglodesc{(\ref {util.smartptr.weak.const})}} {\memgloref{}}|memjustarg}{630} -\glossaryentry{util.smartptr.weak.dest@ {\memgloterm{util.smartptr.weak.dest}}{\memglodesc{(\ref {util.smartptr.weak.dest})}} {\memgloref{}}|memjustarg}{630} -\glossaryentry{util.smartptr.weak.assign@ {\memgloterm{util.smartptr.weak.assign}}{\memglodesc{(\ref {util.smartptr.weak.assign})}} {\memgloref{}}|memjustarg}{631} -\glossaryentry{util.smartptr.weak.mod@ {\memgloterm{util.smartptr.weak.mod}}{\memglodesc{(\ref {util.smartptr.weak.mod})}} {\memgloref{}}|memjustarg}{631} -\glossaryentry{util.smartptr.weak.obs@ {\memgloterm{util.smartptr.weak.obs}}{\memglodesc{(\ref {util.smartptr.weak.obs})}} {\memgloref{}}|memjustarg}{631} -\glossaryentry{util.smartptr.weak.spec@ {\memgloterm{util.smartptr.weak.spec}}{\memglodesc{(\ref {util.smartptr.weak.spec})}} {\memgloref{}}|memjustarg}{631} -\glossaryentry{util.smartptr.ownerless@ {\memgloterm{util.smartptr.ownerless}}{\memglodesc{(\ref {util.smartptr.ownerless})}} {\memgloref{}}|memjustarg}{631} -\glossaryentry{util.smartptr.enab@ {\memgloterm{util.smartptr.enab}}{\memglodesc{(\ref {util.smartptr.enab})}} {\memgloref{}}|memjustarg}{632} -\glossaryentry{util.smartptr.hash@ {\memgloterm{util.smartptr.hash}}{\memglodesc{(\ref {util.smartptr.hash})}} {\memgloref{}}|memjustarg}{633} -\glossaryentry{smartptr.adapt@ {\memgloterm{smartptr.adapt}}{\memglodesc{(\ref {smartptr.adapt})}} {\memgloref{}}|memjustarg}{633} -\glossaryentry{out.ptr.t@ {\memgloterm{out.ptr.t}}{\memglodesc{(\ref {out.ptr.t})}} {\memgloref{}}|memjustarg}{633} -\glossaryentry{out.ptr@ {\memgloterm{out.ptr}}{\memglodesc{(\ref {out.ptr})}} {\memgloref{}}|memjustarg}{635} -\glossaryentry{inout.ptr.t@ {\memgloterm{inout.ptr.t}}{\memglodesc{(\ref {inout.ptr.t})}} {\memgloref{}}|memjustarg}{635} -\glossaryentry{inout.ptr@ {\memgloterm{inout.ptr}}{\memglodesc{(\ref {inout.ptr})}} {\memgloref{}}|memjustarg}{637} -\glossaryentry{mem.res@ {\memgloterm{mem.res}}{\memglodesc{(\ref {mem.res})}} {\memgloref{}}|memjustarg}{637} -\glossaryentry{mem.res.syn@ {\memgloterm{mem.res.syn}}{\memglodesc{(\ref {mem.res.syn})}} {\memgloref{}}|memjustarg}{637} -\glossaryentry{mem.res.class@ {\memgloterm{mem.res.class}}{\memglodesc{(\ref {mem.res.class})}} {\memgloref{}}|memjustarg}{637} -\glossaryentry{mem.res.class.general@ {\memgloterm{mem.res.class.general}}{\memglodesc{(\ref {mem.res.class.general})}} {\memgloref{}}|memjustarg}{637} -\glossaryentry{mem.res.public@ {\memgloterm{mem.res.public}}{\memglodesc{(\ref {mem.res.public})}} {\memgloref{}}|memjustarg}{638} -\glossaryentry{mem.res.private@ {\memgloterm{mem.res.private}}{\memglodesc{(\ref {mem.res.private})}} {\memgloref{}}|memjustarg}{638} -\glossaryentry{mem.res.eq@ {\memgloterm{mem.res.eq}}{\memglodesc{(\ref {mem.res.eq})}} {\memgloref{}}|memjustarg}{639} -\glossaryentry{mem.poly.allocator.class@ {\memgloterm{mem.poly.allocator.class}}{\memglodesc{(\ref {mem.poly.allocator.class})}} {\memgloref{}}|memjustarg}{639} -\glossaryentry{mem.poly.allocator.class.general@ {\memgloterm{mem.poly.allocator.class.general}}{\memglodesc{(\ref {mem.poly.allocator.class.general})}} {\memgloref{}}|memjustarg}{639} -\glossaryentry{mem.poly.allocator.ctor@ {\memgloterm{mem.poly.allocator.ctor}}{\memglodesc{(\ref {mem.poly.allocator.ctor})}} {\memgloref{}}|memjustarg}{640} -\glossaryentry{mem.poly.allocator.mem@ {\memgloterm{mem.poly.allocator.mem}}{\memglodesc{(\ref {mem.poly.allocator.mem})}} {\memgloref{}}|memjustarg}{640} -\glossaryentry{mem.poly.allocator.eq@ {\memgloterm{mem.poly.allocator.eq}}{\memglodesc{(\ref {mem.poly.allocator.eq})}} {\memgloref{}}|memjustarg}{641} -\glossaryentry{mem.res.global@ {\memgloterm{mem.res.global}}{\memglodesc{(\ref {mem.res.global})}} {\memgloref{}}|memjustarg}{641} -\glossaryentry{mem.res.pool@ {\memgloterm{mem.res.pool}}{\memglodesc{(\ref {mem.res.pool})}} {\memgloref{}}|memjustarg}{642} -\glossaryentry{mem.res.pool.overview@ {\memgloterm{mem.res.pool.overview}}{\memglodesc{(\ref {mem.res.pool.overview})}} {\memgloref{}}|memjustarg}{642} -\glossaryentry{mem.res.pool.options@ {\memgloterm{mem.res.pool.options}}{\memglodesc{(\ref {mem.res.pool.options})}} {\memgloref{}}|memjustarg}{643} -\glossaryentry{mem.res.pool.ctor@ {\memgloterm{mem.res.pool.ctor}}{\memglodesc{(\ref {mem.res.pool.ctor})}} {\memgloref{}}|memjustarg}{643} -\glossaryentry{mem.res.pool.mem@ {\memgloterm{mem.res.pool.mem}}{\memglodesc{(\ref {mem.res.pool.mem})}} {\memgloref{}}|memjustarg}{644} -\glossaryentry{mem.res.monotonic.buffer@ {\memgloterm{mem.res.monotonic.buffer}}{\memglodesc{(\ref {mem.res.monotonic.buffer})}} {\memgloref{}}|memjustarg}{644} -\glossaryentry{mem.res.monotonic.buffer.general@ {\memgloterm{mem.res.monotonic.buffer.general}}{\memglodesc{(\ref {mem.res.monotonic.buffer.general})}} {\memgloref{}}|memjustarg}{644} -\glossaryentry{mem.res.monotonic.buffer.ctor@ {\memgloterm{mem.res.monotonic.buffer.ctor}}{\memglodesc{(\ref {mem.res.monotonic.buffer.ctor})}} {\memgloref{}}|memjustarg}{645} -\glossaryentry{mem.res.monotonic.buffer.mem@ {\memgloterm{mem.res.monotonic.buffer.mem}}{\memglodesc{(\ref {mem.res.monotonic.buffer.mem})}} {\memgloref{}}|memjustarg}{645} -\glossaryentry{allocator.adaptor@ {\memgloterm{allocator.adaptor}}{\memglodesc{(\ref {allocator.adaptor})}} {\memgloref{}}|memjustarg}{646} -\glossaryentry{allocator.adaptor.syn@ {\memgloterm{allocator.adaptor.syn}}{\memglodesc{(\ref {allocator.adaptor.syn})}} {\memgloref{}}|memjustarg}{646} -\glossaryentry{allocator.adaptor.types@ {\memgloterm{allocator.adaptor.types}}{\memglodesc{(\ref {allocator.adaptor.types})}} {\memgloref{}}|memjustarg}{647} -\glossaryentry{allocator.adaptor.cnstr@ {\memgloterm{allocator.adaptor.cnstr}}{\memglodesc{(\ref {allocator.adaptor.cnstr})}} {\memgloref{}}|memjustarg}{648} -\glossaryentry{allocator.adaptor.members@ {\memgloterm{allocator.adaptor.members}}{\memglodesc{(\ref {allocator.adaptor.members})}} {\memgloref{}}|memjustarg}{648} -\glossaryentry{scoped.adaptor.operators@ {\memgloterm{scoped.adaptor.operators}}{\memglodesc{(\ref {scoped.adaptor.operators})}} {\memgloref{}}|memjustarg}{649} -\glossaryentry{meta@ {\memgloterm{meta}}{\memglodesc{(\ref {meta})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{meta.general@ {\memgloterm{meta.general}}{\memglodesc{(\ref {meta.general})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{intseq@ {\memgloterm{intseq}}{\memglodesc{(\ref {intseq})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{intseq.general@ {\memgloterm{intseq.general}}{\memglodesc{(\ref {intseq.general})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{intseq.intseq@ {\memgloterm{intseq.intseq}}{\memglodesc{(\ref {intseq.intseq})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{intseq.make@ {\memgloterm{intseq.make}}{\memglodesc{(\ref {intseq.make})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{type.traits@ {\memgloterm{type.traits}}{\memglodesc{(\ref {type.traits})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{type.traits.general@ {\memgloterm{type.traits.general}}{\memglodesc{(\ref {type.traits.general})}} {\memgloref{}}|memjustarg}{650} -\glossaryentry{meta.rqmts@ {\memgloterm{meta.rqmts}}{\memglodesc{(\ref {meta.rqmts})}} {\memgloref{}}|memjustarg}{651} -\glossaryentry{meta.type.synop@ {\memgloterm{meta.type.synop}}{\memglodesc{(\ref {meta.type.synop})}} {\memgloref{}}|memjustarg}{651} -\glossaryentry{meta.help@ {\memgloterm{meta.help}}{\memglodesc{(\ref {meta.help})}} {\memgloref{}}|memjustarg}{658} -\glossaryentry{meta.unary@ {\memgloterm{meta.unary}}{\memglodesc{(\ref {meta.unary})}} {\memgloref{}}|memjustarg}{658} -\glossaryentry{meta.unary.general@ {\memgloterm{meta.unary.general}}{\memglodesc{(\ref {meta.unary.general})}} {\memgloref{}}|memjustarg}{658} -\glossaryentry{meta.unary.cat@ {\memgloterm{meta.unary.cat}}{\memglodesc{(\ref {meta.unary.cat})}} {\memgloref{}}|memjustarg}{658} -\glossaryentry{meta.unary.comp@ {\memgloterm{meta.unary.comp}}{\memglodesc{(\ref {meta.unary.comp})}} {\memgloref{}}|memjustarg}{659} -\glossaryentry{meta.unary.prop@ {\memgloterm{meta.unary.prop}}{\memglodesc{(\ref {meta.unary.prop})}} {\memgloref{}}|memjustarg}{659} -\glossaryentry{meta.unary.prop.query@ {\memgloterm{meta.unary.prop.query}}{\memglodesc{(\ref {meta.unary.prop.query})}} {\memgloref{}}|memjustarg}{666} -\glossaryentry{meta.rel@ {\memgloterm{meta.rel}}{\memglodesc{(\ref {meta.rel})}} {\memgloref{}}|memjustarg}{667} -\glossaryentry{meta.trans@ {\memgloterm{meta.trans}}{\memglodesc{(\ref {meta.trans})}} {\memgloref{}}|memjustarg}{669} -\glossaryentry{meta.trans.general@ {\memgloterm{meta.trans.general}}{\memglodesc{(\ref {meta.trans.general})}} {\memgloref{}}|memjustarg}{669} -\glossaryentry{meta.trans.cv@ {\memgloterm{meta.trans.cv}}{\memglodesc{(\ref {meta.trans.cv})}} {\memgloref{}}|memjustarg}{669} -\glossaryentry{meta.trans.ref@ {\memgloterm{meta.trans.ref}}{\memglodesc{(\ref {meta.trans.ref})}} {\memgloref{}}|memjustarg}{669} -\glossaryentry{meta.trans.sign@ {\memgloterm{meta.trans.sign}}{\memglodesc{(\ref {meta.trans.sign})}} {\memgloref{}}|memjustarg}{670} -\glossaryentry{meta.trans.arr@ {\memgloterm{meta.trans.arr}}{\memglodesc{(\ref {meta.trans.arr})}} {\memgloref{}}|memjustarg}{670} -\glossaryentry{meta.trans.ptr@ {\memgloterm{meta.trans.ptr}}{\memglodesc{(\ref {meta.trans.ptr})}} {\memgloref{}}|memjustarg}{671} -\glossaryentry{meta.trans.other@ {\memgloterm{meta.trans.other}}{\memglodesc{(\ref {meta.trans.other})}} {\memgloref{}}|memjustarg}{671} -\glossaryentry{meta.logical@ {\memgloterm{meta.logical}}{\memglodesc{(\ref {meta.logical})}} {\memgloref{}}|memjustarg}{674} -\glossaryentry{meta.member@ {\memgloterm{meta.member}}{\memglodesc{(\ref {meta.member})}} {\memgloref{}}|memjustarg}{675} -\glossaryentry{meta.const.eval@ {\memgloterm{meta.const.eval}}{\memglodesc{(\ref {meta.const.eval})}} {\memgloref{}}|memjustarg}{675} -\glossaryentry{ratio@ {\memgloterm{ratio}}{\memglodesc{(\ref {ratio})}} {\memgloref{}}|memjustarg}{676} -\glossaryentry{ratio.general@ {\memgloterm{ratio.general}}{\memglodesc{(\ref {ratio.general})}} {\memgloref{}}|memjustarg}{676} -\glossaryentry{ratio.syn@ {\memgloterm{ratio.syn}}{\memglodesc{(\ref {ratio.syn})}} {\memgloref{}}|memjustarg}{676} -\glossaryentry{ratio.ratio@ {\memgloterm{ratio.ratio}}{\memglodesc{(\ref {ratio.ratio})}} {\memgloref{}}|memjustarg}{677} -\glossaryentry{ratio.arithmetic@ {\memgloterm{ratio.arithmetic}}{\memglodesc{(\ref {ratio.arithmetic})}} {\memgloref{}}|memjustarg}{677} -\glossaryentry{ratio.comparison@ {\memgloterm{ratio.comparison}}{\memglodesc{(\ref {ratio.comparison})}} {\memgloref{}}|memjustarg}{678} -\glossaryentry{ratio.si@ {\memgloterm{ratio.si}}{\memglodesc{(\ref {ratio.si})}} {\memgloref{}}|memjustarg}{678} -\glossaryentry{utilities@ {\memgloterm{utilities}}{\memglodesc{(\ref {utilities})}} {\memgloref{}}|memjustarg}{679} -\glossaryentry{utilities.general@ {\memgloterm{utilities.general}}{\memglodesc{(\ref {utilities.general})}} {\memgloref{}}|memjustarg}{679} -\glossaryentry{utility@ {\memgloterm{utility}}{\memglodesc{(\ref {utility})}} {\memgloref{}}|memjustarg}{679} -\glossaryentry{utility.syn@ {\memgloterm{utility.syn}}{\memglodesc{(\ref {utility.syn})}} {\memgloref{}}|memjustarg}{679} -\glossaryentry{utility.swap@ {\memgloterm{utility.swap}}{\memglodesc{(\ref {utility.swap})}} {\memgloref{}}|memjustarg}{682} -\glossaryentry{utility.exchange@ {\memgloterm{utility.exchange}}{\memglodesc{(\ref {utility.exchange})}} {\memgloref{}}|memjustarg}{682} -\glossaryentry{forward@ {\memgloterm{forward}}{\memglodesc{(\ref {forward})}} {\memgloref{}}|memjustarg}{682} -\glossaryentry{utility.as.const@ {\memgloterm{utility.as.const}}{\memglodesc{(\ref {utility.as.const})}} {\memgloref{}}|memjustarg}{684} -\glossaryentry{declval@ {\memgloterm{declval}}{\memglodesc{(\ref {declval})}} {\memgloref{}}|memjustarg}{684} -\glossaryentry{utility.intcmp@ {\memgloterm{utility.intcmp}}{\memglodesc{(\ref {utility.intcmp})}} {\memgloref{}}|memjustarg}{684} -\glossaryentry{utility.underlying@ {\memgloterm{utility.underlying}}{\memglodesc{(\ref {utility.underlying})}} {\memgloref{}}|memjustarg}{685} -\glossaryentry{utility.unreachable@ {\memgloterm{utility.unreachable}}{\memglodesc{(\ref {utility.unreachable})}} {\memgloref{}}|memjustarg}{685} -\glossaryentry{pairs@ {\memgloterm{pairs}}{\memglodesc{(\ref {pairs})}} {\memgloref{}}|memjustarg}{686} -\glossaryentry{pairs.general@ {\memgloterm{pairs.general}}{\memglodesc{(\ref {pairs.general})}} {\memgloref{}}|memjustarg}{686} -\glossaryentry{pairs.pair@ {\memgloterm{pairs.pair}}{\memglodesc{(\ref {pairs.pair})}} {\memgloref{}}|memjustarg}{686} -\glossaryentry{pairs.spec@ {\memgloterm{pairs.spec}}{\memglodesc{(\ref {pairs.spec})}} {\memgloref{}}|memjustarg}{690} -\glossaryentry{pair.astuple@ {\memgloterm{pair.astuple}}{\memglodesc{(\ref {pair.astuple})}} {\memgloref{}}|memjustarg}{690} -\glossaryentry{pair.piecewise@ {\memgloterm{pair.piecewise}}{\memglodesc{(\ref {pair.piecewise})}} {\memgloref{}}|memjustarg}{691} -\glossaryentry{tuple@ {\memgloterm{tuple}}{\memglodesc{(\ref {tuple})}} {\memgloref{}}|memjustarg}{691} -\glossaryentry{tuple.general@ {\memgloterm{tuple.general}}{\memglodesc{(\ref {tuple.general})}} {\memgloref{}}|memjustarg}{691} -\glossaryentry{tuple.syn@ {\memgloterm{tuple.syn}}{\memglodesc{(\ref {tuple.syn})}} {\memgloref{}}|memjustarg}{692} -\glossaryentry{tuple.like@ {\memgloterm{tuple.like}}{\memglodesc{(\ref {tuple.like})}} {\memgloref{}}|memjustarg}{693} -\glossaryentry{tuple.tuple@ {\memgloterm{tuple.tuple}}{\memglodesc{(\ref {tuple.tuple})}} {\memgloref{}}|memjustarg}{693} -\glossaryentry{tuple.cnstr@ {\memgloterm{tuple.cnstr}}{\memglodesc{(\ref {tuple.cnstr})}} {\memgloref{}}|memjustarg}{695} -\glossaryentry{tuple.assign@ {\memgloterm{tuple.assign}}{\memglodesc{(\ref {tuple.assign})}} {\memgloref{}}|memjustarg}{698} -\glossaryentry{tuple.swap@ {\memgloterm{tuple.swap}}{\memglodesc{(\ref {tuple.swap})}} {\memgloref{}}|memjustarg}{700} -\glossaryentry{tuple.creation@ {\memgloterm{tuple.creation}}{\memglodesc{(\ref {tuple.creation})}} {\memgloref{}}|memjustarg}{701} -\glossaryentry{tuple.apply@ {\memgloterm{tuple.apply}}{\memglodesc{(\ref {tuple.apply})}} {\memgloref{}}|memjustarg}{702} -\glossaryentry{tuple.helper@ {\memgloterm{tuple.helper}}{\memglodesc{(\ref {tuple.helper})}} {\memgloref{}}|memjustarg}{702} -\glossaryentry{tuple.elem@ {\memgloterm{tuple.elem}}{\memglodesc{(\ref {tuple.elem})}} {\memgloref{}}|memjustarg}{703} -\glossaryentry{tuple.rel@ {\memgloterm{tuple.rel}}{\memglodesc{(\ref {tuple.rel})}} {\memgloref{}}|memjustarg}{704} -\glossaryentry{tuple.common.ref@ {\memgloterm{tuple.common.ref}}{\memglodesc{(\ref {tuple.common.ref})}} {\memgloref{}}|memjustarg}{704} -\glossaryentry{tuple.traits@ {\memgloterm{tuple.traits}}{\memglodesc{(\ref {tuple.traits})}} {\memgloref{}}|memjustarg}{705} -\glossaryentry{tuple.special@ {\memgloterm{tuple.special}}{\memglodesc{(\ref {tuple.special})}} {\memgloref{}}|memjustarg}{705} -\glossaryentry{optional@ {\memgloterm{optional}}{\memglodesc{(\ref {optional})}} {\memgloref{}}|memjustarg}{705} -\glossaryentry{optional.general@ {\memgloterm{optional.general}}{\memglodesc{(\ref {optional.general})}} {\memgloref{}}|memjustarg}{705} -\glossaryentry{optional.syn@ {\memgloterm{optional.syn}}{\memglodesc{(\ref {optional.syn})}} {\memgloref{}}|memjustarg}{705} -\glossaryentry{optional.optional@ {\memgloterm{optional.optional}}{\memglodesc{(\ref {optional.optional})}} {\memgloref{}}|memjustarg}{707} -\glossaryentry{optional.optional.general@ {\memgloterm{optional.optional.general}}{\memglodesc{(\ref {optional.optional.general})}} {\memgloref{}}|memjustarg}{707} -\glossaryentry{optional.ctor@ {\memgloterm{optional.ctor}}{\memglodesc{(\ref {optional.ctor})}} {\memgloref{}}|memjustarg}{708} -\glossaryentry{optional.dtor@ {\memgloterm{optional.dtor}}{\memglodesc{(\ref {optional.dtor})}} {\memgloref{}}|memjustarg}{710} -\glossaryentry{optional.assign@ {\memgloterm{optional.assign}}{\memglodesc{(\ref {optional.assign})}} {\memgloref{}}|memjustarg}{710} -\glossaryentry{optional.swap@ {\memgloterm{optional.swap}}{\memglodesc{(\ref {optional.swap})}} {\memgloref{}}|memjustarg}{713} -\glossaryentry{optional.observe@ {\memgloterm{optional.observe}}{\memglodesc{(\ref {optional.observe})}} {\memgloref{}}|memjustarg}{713} -\glossaryentry{optional.monadic@ {\memgloterm{optional.monadic}}{\memglodesc{(\ref {optional.monadic})}} {\memgloref{}}|memjustarg}{714} -\glossaryentry{optional.mod@ {\memgloterm{optional.mod}}{\memglodesc{(\ref {optional.mod})}} {\memgloref{}}|memjustarg}{715} -\glossaryentry{optional.nullopt@ {\memgloterm{optional.nullopt}}{\memglodesc{(\ref {optional.nullopt})}} {\memgloref{}}|memjustarg}{715} -\glossaryentry{optional.bad.access@ {\memgloterm{optional.bad.access}}{\memglodesc{(\ref {optional.bad.access})}} {\memgloref{}}|memjustarg}{716} -\glossaryentry{optional.relops@ {\memgloterm{optional.relops}}{\memglodesc{(\ref {optional.relops})}} {\memgloref{}}|memjustarg}{716} -\glossaryentry{optional.nullops@ {\memgloterm{optional.nullops}}{\memglodesc{(\ref {optional.nullops})}} {\memgloref{}}|memjustarg}{717} -\glossaryentry{optional.comp.with.t@ {\memgloterm{optional.comp.with.t}}{\memglodesc{(\ref {optional.comp.with.t})}} {\memgloref{}}|memjustarg}{717} -\glossaryentry{optional.specalg@ {\memgloterm{optional.specalg}}{\memglodesc{(\ref {optional.specalg})}} {\memgloref{}}|memjustarg}{718} -\glossaryentry{optional.hash@ {\memgloterm{optional.hash}}{\memglodesc{(\ref {optional.hash})}} {\memgloref{}}|memjustarg}{718} -\glossaryentry{variant@ {\memgloterm{variant}}{\memglodesc{(\ref {variant})}} {\memgloref{}}|memjustarg}{718} -\glossaryentry{variant.general@ {\memgloterm{variant.general}}{\memglodesc{(\ref {variant.general})}} {\memgloref{}}|memjustarg}{718} -\glossaryentry{variant.syn@ {\memgloterm{variant.syn}}{\memglodesc{(\ref {variant.syn})}} {\memgloref{}}|memjustarg}{718} -\glossaryentry{variant.variant@ {\memgloterm{variant.variant}}{\memglodesc{(\ref {variant.variant})}} {\memgloref{}}|memjustarg}{720} -\glossaryentry{variant.variant.general@ {\memgloterm{variant.variant.general}}{\memglodesc{(\ref {variant.variant.general})}} {\memgloref{}}|memjustarg}{720} -\glossaryentry{variant.ctor@ {\memgloterm{variant.ctor}}{\memglodesc{(\ref {variant.ctor})}} {\memgloref{}}|memjustarg}{721} -\glossaryentry{variant.dtor@ {\memgloterm{variant.dtor}}{\memglodesc{(\ref {variant.dtor})}} {\memgloref{}}|memjustarg}{723} -\glossaryentry{variant.assign@ {\memgloterm{variant.assign}}{\memglodesc{(\ref {variant.assign})}} {\memgloref{}}|memjustarg}{723} -\glossaryentry{variant.mod@ {\memgloterm{variant.mod}}{\memglodesc{(\ref {variant.mod})}} {\memgloref{}}|memjustarg}{725} -\glossaryentry{variant.status@ {\memgloterm{variant.status}}{\memglodesc{(\ref {variant.status})}} {\memgloref{}}|memjustarg}{725} -\glossaryentry{variant.swap@ {\memgloterm{variant.swap}}{\memglodesc{(\ref {variant.swap})}} {\memgloref{}}|memjustarg}{726} -\glossaryentry{variant.helper@ {\memgloterm{variant.helper}}{\memglodesc{(\ref {variant.helper})}} {\memgloref{}}|memjustarg}{726} -\glossaryentry{variant.get@ {\memgloterm{variant.get}}{\memglodesc{(\ref {variant.get})}} {\memgloref{}}|memjustarg}{726} -\glossaryentry{variant.relops@ {\memgloterm{variant.relops}}{\memglodesc{(\ref {variant.relops})}} {\memgloref{}}|memjustarg}{727} -\glossaryentry{variant.visit@ {\memgloterm{variant.visit}}{\memglodesc{(\ref {variant.visit})}} {\memgloref{}}|memjustarg}{728} -\glossaryentry{variant.monostate@ {\memgloterm{variant.monostate}}{\memglodesc{(\ref {variant.monostate})}} {\memgloref{}}|memjustarg}{729} -\glossaryentry{variant.monostate.relops@ {\memgloterm{variant.monostate.relops}}{\memglodesc{(\ref {variant.monostate.relops})}} {\memgloref{}}|memjustarg}{729} -\glossaryentry{variant.specalg@ {\memgloterm{variant.specalg}}{\memglodesc{(\ref {variant.specalg})}} {\memgloref{}}|memjustarg}{729} -\glossaryentry{variant.bad.access@ {\memgloterm{variant.bad.access}}{\memglodesc{(\ref {variant.bad.access})}} {\memgloref{}}|memjustarg}{729} -\glossaryentry{variant.hash@ {\memgloterm{variant.hash}}{\memglodesc{(\ref {variant.hash})}} {\memgloref{}}|memjustarg}{729} -\glossaryentry{any@ {\memgloterm{any}}{\memglodesc{(\ref {any})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.general@ {\memgloterm{any.general}}{\memglodesc{(\ref {any.general})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.synop@ {\memgloterm{any.synop}}{\memglodesc{(\ref {any.synop})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.bad.any.cast@ {\memgloterm{any.bad.any.cast}}{\memglodesc{(\ref {any.bad.any.cast})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.class@ {\memgloterm{any.class}}{\memglodesc{(\ref {any.class})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.class.general@ {\memgloterm{any.class.general}}{\memglodesc{(\ref {any.class.general})}} {\memgloref{}}|memjustarg}{730} -\glossaryentry{any.cons@ {\memgloterm{any.cons}}{\memglodesc{(\ref {any.cons})}} {\memgloref{}}|memjustarg}{731} -\glossaryentry{any.assign@ {\memgloterm{any.assign}}{\memglodesc{(\ref {any.assign})}} {\memgloref{}}|memjustarg}{732} -\glossaryentry{any.modifiers@ {\memgloterm{any.modifiers}}{\memglodesc{(\ref {any.modifiers})}} {\memgloref{}}|memjustarg}{733} -\glossaryentry{any.observers@ {\memgloterm{any.observers}}{\memglodesc{(\ref {any.observers})}} {\memgloref{}}|memjustarg}{733} -\glossaryentry{any.nonmembers@ {\memgloterm{any.nonmembers}}{\memglodesc{(\ref {any.nonmembers})}} {\memgloref{}}|memjustarg}{734} -\glossaryentry{expected@ {\memgloterm{expected}}{\memglodesc{(\ref {expected})}} {\memgloref{}}|memjustarg}{735} -\glossaryentry{expected.general@ {\memgloterm{expected.general}}{\memglodesc{(\ref {expected.general})}} {\memgloref{}}|memjustarg}{735} -\glossaryentry{expected.syn@ {\memgloterm{expected.syn}}{\memglodesc{(\ref {expected.syn})}} {\memgloref{}}|memjustarg}{735} -\glossaryentry{expected.unexpected@ {\memgloterm{expected.unexpected}}{\memglodesc{(\ref {expected.unexpected})}} {\memgloref{}}|memjustarg}{735} -\glossaryentry{expected.un.general@ {\memgloterm{expected.un.general}}{\memglodesc{(\ref {expected.un.general})}} {\memgloref{}}|memjustarg}{735} -\glossaryentry{expected.un.cons@ {\memgloterm{expected.un.cons}}{\memglodesc{(\ref {expected.un.cons})}} {\memgloref{}}|memjustarg}{736} -\glossaryentry{expected.un.obs@ {\memgloterm{expected.un.obs}}{\memglodesc{(\ref {expected.un.obs})}} {\memgloref{}}|memjustarg}{736} -\glossaryentry{expected.un.swap@ {\memgloterm{expected.un.swap}}{\memglodesc{(\ref {expected.un.swap})}} {\memgloref{}}|memjustarg}{736} -\glossaryentry{expected.un.eq@ {\memgloterm{expected.un.eq}}{\memglodesc{(\ref {expected.un.eq})}} {\memgloref{}}|memjustarg}{737} -\glossaryentry{expected.bad@ {\memgloterm{expected.bad}}{\memglodesc{(\ref {expected.bad})}} {\memgloref{}}|memjustarg}{737} -\glossaryentry{expected.bad.void@ {\memgloterm{expected.bad.void}}{\memglodesc{(\ref {expected.bad.void})}} {\memgloref{}}|memjustarg}{737} -\glossaryentry{expected.expected@ {\memgloterm{expected.expected}}{\memglodesc{(\ref {expected.expected})}} {\memgloref{}}|memjustarg}{738} -\glossaryentry{expected.object.general@ {\memgloterm{expected.object.general}}{\memglodesc{(\ref {expected.object.general})}} {\memgloref{}}|memjustarg}{738} -\glossaryentry{expected.object.cons@ {\memgloterm{expected.object.cons}}{\memglodesc{(\ref {expected.object.cons})}} {\memgloref{}}|memjustarg}{740} -\glossaryentry{expected.object.dtor@ {\memgloterm{expected.object.dtor}}{\memglodesc{(\ref {expected.object.dtor})}} {\memgloref{}}|memjustarg}{742} -\glossaryentry{expected.object.assign@ {\memgloterm{expected.object.assign}}{\memglodesc{(\ref {expected.object.assign})}} {\memgloref{}}|memjustarg}{742} -\glossaryentry{expected.object.swap@ {\memgloterm{expected.object.swap}}{\memglodesc{(\ref {expected.object.swap})}} {\memgloref{}}|memjustarg}{744} -\glossaryentry{expected.object.obs@ {\memgloterm{expected.object.obs}}{\memglodesc{(\ref {expected.object.obs})}} {\memgloref{}}|memjustarg}{745} -\glossaryentry{expected.object.monadic@ {\memgloterm{expected.object.monadic}}{\memglodesc{(\ref {expected.object.monadic})}} {\memgloref{}}|memjustarg}{746} -\glossaryentry{expected.object.eq@ {\memgloterm{expected.object.eq}}{\memglodesc{(\ref {expected.object.eq})}} {\memgloref{}}|memjustarg}{748} -\glossaryentry{expected.void@ {\memgloterm{expected.void}}{\memglodesc{(\ref {expected.void})}} {\memgloref{}}|memjustarg}{749} -\glossaryentry{expected.void.general@ {\memgloterm{expected.void.general}}{\memglodesc{(\ref {expected.void.general})}} {\memgloref{}}|memjustarg}{749} -\glossaryentry{expected.void.cons@ {\memgloterm{expected.void.cons}}{\memglodesc{(\ref {expected.void.cons})}} {\memgloref{}}|memjustarg}{750} -\glossaryentry{expected.void.dtor@ {\memgloterm{expected.void.dtor}}{\memglodesc{(\ref {expected.void.dtor})}} {\memgloref{}}|memjustarg}{751} -\glossaryentry{expected.void.assign@ {\memgloterm{expected.void.assign}}{\memglodesc{(\ref {expected.void.assign})}} {\memgloref{}}|memjustarg}{752} -\glossaryentry{expected.void.swap@ {\memgloterm{expected.void.swap}}{\memglodesc{(\ref {expected.void.swap})}} {\memgloref{}}|memjustarg}{752} -\glossaryentry{expected.void.obs@ {\memgloterm{expected.void.obs}}{\memglodesc{(\ref {expected.void.obs})}} {\memgloref{}}|memjustarg}{753} -\glossaryentry{expected.void.monadic@ {\memgloterm{expected.void.monadic}}{\memglodesc{(\ref {expected.void.monadic})}} {\memgloref{}}|memjustarg}{753} -\glossaryentry{expected.void.eq@ {\memgloterm{expected.void.eq}}{\memglodesc{(\ref {expected.void.eq})}} {\memgloref{}}|memjustarg}{755} -\glossaryentry{bitset@ {\memgloterm{bitset}}{\memglodesc{(\ref {bitset})}} {\memgloref{}}|memjustarg}{755} -\glossaryentry{bitset.syn@ {\memgloterm{bitset.syn}}{\memglodesc{(\ref {bitset.syn})}} {\memgloref{}}|memjustarg}{755} -\glossaryentry{template.bitset@ {\memgloterm{template.bitset}}{\memglodesc{(\ref {template.bitset})}} {\memgloref{}}|memjustarg}{756} -\glossaryentry{template.bitset.general@ {\memgloterm{template.bitset.general}}{\memglodesc{(\ref {template.bitset.general})}} {\memgloref{}}|memjustarg}{756} -\glossaryentry{bitset.cons@ {\memgloterm{bitset.cons}}{\memglodesc{(\ref {bitset.cons})}} {\memgloref{}}|memjustarg}{757} -\glossaryentry{bitset.members@ {\memgloterm{bitset.members}}{\memglodesc{(\ref {bitset.members})}} {\memgloref{}}|memjustarg}{758} -\glossaryentry{bitset.hash@ {\memgloterm{bitset.hash}}{\memglodesc{(\ref {bitset.hash})}} {\memgloref{}}|memjustarg}{760} -\glossaryentry{bitset.operators@ {\memgloterm{bitset.operators}}{\memglodesc{(\ref {bitset.operators})}} {\memgloref{}}|memjustarg}{760} -\glossaryentry{function.objects@ {\memgloterm{function.objects}}{\memglodesc{(\ref {function.objects})}} {\memgloref{}}|memjustarg}{761} -\glossaryentry{function.objects.general@ {\memgloterm{function.objects.general}}{\memglodesc{(\ref {function.objects.general})}} {\memgloref{}}|memjustarg}{761} -\glossaryentry{functional.syn@ {\memgloterm{functional.syn}}{\memglodesc{(\ref {functional.syn})}} {\memgloref{}}|memjustarg}{761} -\glossaryentry{func.def@ {\memgloterm{func.def}}{\memglodesc{(\ref {func.def})}} {\memgloref{}}|memjustarg}{764} -\glossaryentry{func.require@ {\memgloterm{func.require}}{\memglodesc{(\ref {func.require})}} {\memgloref{}}|memjustarg}{764} -\glossaryentry{func.invoke@ {\memgloterm{func.invoke}}{\memglodesc{(\ref {func.invoke})}} {\memgloref{}}|memjustarg}{765} -\glossaryentry{refwrap@ {\memgloterm{refwrap}}{\memglodesc{(\ref {refwrap})}} {\memgloref{}}|memjustarg}{766} -\glossaryentry{refwrap.general@ {\memgloterm{refwrap.general}}{\memglodesc{(\ref {refwrap.general})}} {\memgloref{}}|memjustarg}{766} -\glossaryentry{refwrap.const@ {\memgloterm{refwrap.const}}{\memglodesc{(\ref {refwrap.const})}} {\memgloref{}}|memjustarg}{766} -\glossaryentry{refwrap.assign@ {\memgloterm{refwrap.assign}}{\memglodesc{(\ref {refwrap.assign})}} {\memgloref{}}|memjustarg}{766} -\glossaryentry{refwrap.access@ {\memgloterm{refwrap.access}}{\memglodesc{(\ref {refwrap.access})}} {\memgloref{}}|memjustarg}{766} -\glossaryentry{refwrap.invoke@ {\memgloterm{refwrap.invoke}}{\memglodesc{(\ref {refwrap.invoke})}} {\memgloref{}}|memjustarg}{767} -\glossaryentry{refwrap.helpers@ {\memgloterm{refwrap.helpers}}{\memglodesc{(\ref {refwrap.helpers})}} {\memgloref{}}|memjustarg}{767} -\glossaryentry{refwrap.common.ref@ {\memgloterm{refwrap.common.ref}}{\memglodesc{(\ref {refwrap.common.ref})}} {\memgloref{}}|memjustarg}{767} -\glossaryentry{arithmetic.operations@ {\memgloterm{arithmetic.operations}}{\memglodesc{(\ref {arithmetic.operations})}} {\memgloref{}}|memjustarg}{767} -\glossaryentry{arithmetic.operations.general@ {\memgloterm{arithmetic.operations.general}}{\memglodesc{(\ref {arithmetic.operations.general})}} {\memgloref{}}|memjustarg}{767} -\glossaryentry{arithmetic.operations.plus@ {\memgloterm{arithmetic.operations.plus}}{\memglodesc{(\ref {arithmetic.operations.plus})}} {\memgloref{}}|memjustarg}{768} -\glossaryentry{arithmetic.operations.minus@ {\memgloterm{arithmetic.operations.minus}}{\memglodesc{(\ref {arithmetic.operations.minus})}} {\memgloref{}}|memjustarg}{768} -\glossaryentry{arithmetic.operations.multiplies@ {\memgloterm{arithmetic.operations.multiplies}}{\memglodesc{(\ref {arithmetic.operations.multiplies})}} {\memgloref{}}|memjustarg}{768} -\glossaryentry{arithmetic.operations.divides@ {\memgloterm{arithmetic.operations.divides}}{\memglodesc{(\ref {arithmetic.operations.divides})}} {\memgloref{}}|memjustarg}{768} -\glossaryentry{arithmetic.operations.modulus@ {\memgloterm{arithmetic.operations.modulus}}{\memglodesc{(\ref {arithmetic.operations.modulus})}} {\memgloref{}}|memjustarg}{769} -\glossaryentry{arithmetic.operations.negate@ {\memgloterm{arithmetic.operations.negate}}{\memglodesc{(\ref {arithmetic.operations.negate})}} {\memgloref{}}|memjustarg}{769} -\glossaryentry{comparisons@ {\memgloterm{comparisons}}{\memglodesc{(\ref {comparisons})}} {\memgloref{}}|memjustarg}{769} -\glossaryentry{comparisons.general@ {\memgloterm{comparisons.general}}{\memglodesc{(\ref {comparisons.general})}} {\memgloref{}}|memjustarg}{769} -\glossaryentry{comparisons.equal.to@ {\memgloterm{comparisons.equal.to}}{\memglodesc{(\ref {comparisons.equal.to})}} {\memgloref{}}|memjustarg}{770} -\glossaryentry{comparisons.not.equal.to@ {\memgloterm{comparisons.not.equal.to}}{\memglodesc{(\ref {comparisons.not.equal.to})}} {\memgloref{}}|memjustarg}{770} -\glossaryentry{comparisons.greater@ {\memgloterm{comparisons.greater}}{\memglodesc{(\ref {comparisons.greater})}} {\memgloref{}}|memjustarg}{770} -\glossaryentry{comparisons.less@ {\memgloterm{comparisons.less}}{\memglodesc{(\ref {comparisons.less})}} {\memgloref{}}|memjustarg}{771} -\glossaryentry{comparisons.greater.equal@ {\memgloterm{comparisons.greater.equal}}{\memglodesc{(\ref {comparisons.greater.equal})}} {\memgloref{}}|memjustarg}{771} -\glossaryentry{comparisons.less.equal@ {\memgloterm{comparisons.less.equal}}{\memglodesc{(\ref {comparisons.less.equal})}} {\memgloref{}}|memjustarg}{771} -\glossaryentry{comparisons.three.way@ {\memgloterm{comparisons.three.way}}{\memglodesc{(\ref {comparisons.three.way})}} {\memgloref{}}|memjustarg}{772} -\glossaryentry{range.cmp@ {\memgloterm{range.cmp}}{\memglodesc{(\ref {range.cmp})}} {\memgloref{}}|memjustarg}{772} -\glossaryentry{logical.operations@ {\memgloterm{logical.operations}}{\memglodesc{(\ref {logical.operations})}} {\memgloref{}}|memjustarg}{774} -\glossaryentry{logical.operations.general@ {\memgloterm{logical.operations.general}}{\memglodesc{(\ref {logical.operations.general})}} {\memgloref{}}|memjustarg}{774} -\glossaryentry{logical.operations.and@ {\memgloterm{logical.operations.and}}{\memglodesc{(\ref {logical.operations.and})}} {\memgloref{}}|memjustarg}{774} -\glossaryentry{logical.operations.or@ {\memgloterm{logical.operations.or}}{\memglodesc{(\ref {logical.operations.or})}} {\memgloref{}}|memjustarg}{774} -\glossaryentry{logical.operations.not@ {\memgloterm{logical.operations.not}}{\memglodesc{(\ref {logical.operations.not})}} {\memgloref{}}|memjustarg}{774} -\glossaryentry{bitwise.operations@ {\memgloterm{bitwise.operations}}{\memglodesc{(\ref {bitwise.operations})}} {\memgloref{}}|memjustarg}{775} -\glossaryentry{bitwise.operations.general@ {\memgloterm{bitwise.operations.general}}{\memglodesc{(\ref {bitwise.operations.general})}} {\memgloref{}}|memjustarg}{775} -\glossaryentry{bitwise.operations.and@ {\memgloterm{bitwise.operations.and}}{\memglodesc{(\ref {bitwise.operations.and})}} {\memgloref{}}|memjustarg}{775} -\glossaryentry{bitwise.operations.or@ {\memgloterm{bitwise.operations.or}}{\memglodesc{(\ref {bitwise.operations.or})}} {\memgloref{}}|memjustarg}{775} -\glossaryentry{bitwise.operations.xor@ {\memgloterm{bitwise.operations.xor}}{\memglodesc{(\ref {bitwise.operations.xor})}} {\memgloref{}}|memjustarg}{775} -\glossaryentry{bitwise.operations.not@ {\memgloterm{bitwise.operations.not}}{\memglodesc{(\ref {bitwise.operations.not})}} {\memgloref{}}|memjustarg}{776} -\glossaryentry{func.identity@ {\memgloterm{func.identity}}{\memglodesc{(\ref {func.identity})}} {\memgloref{}}|memjustarg}{776} -\glossaryentry{func.not.fn@ {\memgloterm{func.not.fn}}{\memglodesc{(\ref {func.not.fn})}} {\memgloref{}}|memjustarg}{776} -\glossaryentry{func.bind.partial@ {\memgloterm{func.bind.partial}}{\memglodesc{(\ref {func.bind.partial})}} {\memgloref{}}|memjustarg}{776} -\glossaryentry{func.bind@ {\memgloterm{func.bind}}{\memglodesc{(\ref {func.bind})}} {\memgloref{}}|memjustarg}{777} -\glossaryentry{func.bind.general@ {\memgloterm{func.bind.general}}{\memglodesc{(\ref {func.bind.general})}} {\memgloref{}}|memjustarg}{777} -\glossaryentry{func.bind.isbind@ {\memgloterm{func.bind.isbind}}{\memglodesc{(\ref {func.bind.isbind})}} {\memgloref{}}|memjustarg}{777} -\glossaryentry{func.bind.isplace@ {\memgloterm{func.bind.isplace}}{\memglodesc{(\ref {func.bind.isplace})}} {\memgloref{}}|memjustarg}{777} -\glossaryentry{func.bind.bind@ {\memgloterm{func.bind.bind}}{\memglodesc{(\ref {func.bind.bind})}} {\memgloref{}}|memjustarg}{777} -\glossaryentry{func.bind.place@ {\memgloterm{func.bind.place}}{\memglodesc{(\ref {func.bind.place})}} {\memgloref{}}|memjustarg}{778} -\glossaryentry{func.memfn@ {\memgloterm{func.memfn}}{\memglodesc{(\ref {func.memfn})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap@ {\memgloterm{func.wrap}}{\memglodesc{(\ref {func.wrap})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap.general@ {\memgloterm{func.wrap.general}}{\memglodesc{(\ref {func.wrap.general})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap.badcall@ {\memgloterm{func.wrap.badcall}}{\memglodesc{(\ref {func.wrap.badcall})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap.func@ {\memgloterm{func.wrap.func}}{\memglodesc{(\ref {func.wrap.func})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap.func.general@ {\memgloterm{func.wrap.func.general}}{\memglodesc{(\ref {func.wrap.func.general})}} {\memgloref{}}|memjustarg}{779} -\glossaryentry{func.wrap.func.con@ {\memgloterm{func.wrap.func.con}}{\memglodesc{(\ref {func.wrap.func.con})}} {\memgloref{}}|memjustarg}{780} -\glossaryentry{func.wrap.func.mod@ {\memgloterm{func.wrap.func.mod}}{\memglodesc{(\ref {func.wrap.func.mod})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.func.cap@ {\memgloterm{func.wrap.func.cap}}{\memglodesc{(\ref {func.wrap.func.cap})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.func.inv@ {\memgloterm{func.wrap.func.inv}}{\memglodesc{(\ref {func.wrap.func.inv})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.func.targ@ {\memgloterm{func.wrap.func.targ}}{\memglodesc{(\ref {func.wrap.func.targ})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.func.nullptr@ {\memgloterm{func.wrap.func.nullptr}}{\memglodesc{(\ref {func.wrap.func.nullptr})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.func.alg@ {\memgloterm{func.wrap.func.alg}}{\memglodesc{(\ref {func.wrap.func.alg})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.move@ {\memgloterm{func.wrap.move}}{\memglodesc{(\ref {func.wrap.move})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.move.general@ {\memgloterm{func.wrap.move.general}}{\memglodesc{(\ref {func.wrap.move.general})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.move.class@ {\memgloterm{func.wrap.move.class}}{\memglodesc{(\ref {func.wrap.move.class})}} {\memgloref{}}|memjustarg}{782} -\glossaryentry{func.wrap.move.ctor@ {\memgloterm{func.wrap.move.ctor}}{\memglodesc{(\ref {func.wrap.move.ctor})}} {\memgloref{}}|memjustarg}{783} -\glossaryentry{func.wrap.move.inv@ {\memgloterm{func.wrap.move.inv}}{\memglodesc{(\ref {func.wrap.move.inv})}} {\memgloref{}}|memjustarg}{785} -\glossaryentry{func.wrap.move.util@ {\memgloterm{func.wrap.move.util}}{\memglodesc{(\ref {func.wrap.move.util})}} {\memgloref{}}|memjustarg}{785} -\glossaryentry{func.search@ {\memgloterm{func.search}}{\memglodesc{(\ref {func.search})}} {\memgloref{}}|memjustarg}{785} -\glossaryentry{func.search.general@ {\memgloterm{func.search.general}}{\memglodesc{(\ref {func.search.general})}} {\memgloref{}}|memjustarg}{785} -\glossaryentry{func.search.default@ {\memgloterm{func.search.default}}{\memglodesc{(\ref {func.search.default})}} {\memgloref{}}|memjustarg}{786} -\glossaryentry{func.search.bm@ {\memgloterm{func.search.bm}}{\memglodesc{(\ref {func.search.bm})}} {\memgloref{}}|memjustarg}{786} -\glossaryentry{func.search.bmh@ {\memgloterm{func.search.bmh}}{\memglodesc{(\ref {func.search.bmh})}} {\memgloref{}}|memjustarg}{787} -\glossaryentry{unord.hash@ {\memgloterm{unord.hash}}{\memglodesc{(\ref {unord.hash})}} {\memgloref{}}|memjustarg}{788} -\glossaryentry{type.index@ {\memgloterm{type.index}}{\memglodesc{(\ref {type.index})}} {\memgloref{}}|memjustarg}{789} -\glossaryentry{type.index.synopsis@ {\memgloterm{type.index.synopsis}}{\memglodesc{(\ref {type.index.synopsis})}} {\memgloref{}}|memjustarg}{789} -\glossaryentry{type.index.overview@ {\memgloterm{type.index.overview}}{\memglodesc{(\ref {type.index.overview})}} {\memgloref{}}|memjustarg}{789} -\glossaryentry{type.index.members@ {\memgloterm{type.index.members}}{\memglodesc{(\ref {type.index.members})}} {\memgloref{}}|memjustarg}{789} -\glossaryentry{type.index.hash@ {\memgloterm{type.index.hash}}{\memglodesc{(\ref {type.index.hash})}} {\memgloref{}}|memjustarg}{790} -\glossaryentry{execpol@ {\memgloterm{execpol}}{\memglodesc{(\ref {execpol})}} {\memgloref{}}|memjustarg}{790} -\glossaryentry{execpol.general@ {\memgloterm{execpol.general}}{\memglodesc{(\ref {execpol.general})}} {\memgloref{}}|memjustarg}{790} -\glossaryentry{execution.syn@ {\memgloterm{execution.syn}}{\memglodesc{(\ref {execution.syn})}} {\memgloref{}}|memjustarg}{790} -\glossaryentry{execpol.type@ {\memgloterm{execpol.type}}{\memglodesc{(\ref {execpol.type})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{execpol.seq@ {\memgloterm{execpol.seq}}{\memglodesc{(\ref {execpol.seq})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{execpol.par@ {\memgloterm{execpol.par}}{\memglodesc{(\ref {execpol.par})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{execpol.parunseq@ {\memgloterm{execpol.parunseq}}{\memglodesc{(\ref {execpol.parunseq})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{execpol.unseq@ {\memgloterm{execpol.unseq}}{\memglodesc{(\ref {execpol.unseq})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{execpol.objects@ {\memgloterm{execpol.objects}}{\memglodesc{(\ref {execpol.objects})}} {\memgloref{}}|memjustarg}{791} -\glossaryentry{charconv@ {\memgloterm{charconv}}{\memglodesc{(\ref {charconv})}} {\memgloref{}}|memjustarg}{792} -\glossaryentry{charconv.syn@ {\memgloterm{charconv.syn}}{\memglodesc{(\ref {charconv.syn})}} {\memgloref{}}|memjustarg}{792} -\glossaryentry{charconv.to.chars@ {\memgloterm{charconv.to.chars}}{\memglodesc{(\ref {charconv.to.chars})}} {\memgloref{}}|memjustarg}{792} -\glossaryentry{charconv.from.chars@ {\memgloterm{charconv.from.chars}}{\memglodesc{(\ref {charconv.from.chars})}} {\memgloref{}}|memjustarg}{793} -\glossaryentry{format@ {\memgloterm{format}}{\memglodesc{(\ref {format})}} {\memgloref{}}|memjustarg}{794} -\glossaryentry{format.syn@ {\memgloterm{format.syn}}{\memglodesc{(\ref {format.syn})}} {\memgloref{}}|memjustarg}{794} -\glossaryentry{format.string@ {\memgloterm{format.string}}{\memglodesc{(\ref {format.string})}} {\memgloref{}}|memjustarg}{796} -\glossaryentry{format.string.general@ {\memgloterm{format.string.general}}{\memglodesc{(\ref {format.string.general})}} {\memgloref{}}|memjustarg}{796} -\glossaryentry{format.string.std@ {\memgloterm{format.string.std}}{\memglodesc{(\ref {format.string.std})}} {\memgloref{}}|memjustarg}{798} -\glossaryentry{format.err.report@ {\memgloterm{format.err.report}}{\memglodesc{(\ref {format.err.report})}} {\memgloref{}}|memjustarg}{802} -\glossaryentry{format.fmt.string@ {\memgloterm{format.fmt.string}}{\memglodesc{(\ref {format.fmt.string})}} {\memgloref{}}|memjustarg}{802} -\glossaryentry{format.functions@ {\memgloterm{format.functions}}{\memglodesc{(\ref {format.functions})}} {\memgloref{}}|memjustarg}{803} -\glossaryentry{format.formatter@ {\memgloterm{format.formatter}}{\memglodesc{(\ref {format.formatter})}} {\memgloref{}}|memjustarg}{805} -\glossaryentry{formatter.requirements@ {\memgloterm{formatter.requirements}}{\memglodesc{(\ref {formatter.requirements})}} {\memgloref{}}|memjustarg}{805} -\glossaryentry{format.formattable@ {\memgloterm{format.formattable}}{\memglodesc{(\ref {format.formattable})}} {\memgloref{}}|memjustarg}{805} -\glossaryentry{format.formatter.spec@ {\memgloterm{format.formatter.spec}}{\memglodesc{(\ref {format.formatter.spec})}} {\memgloref{}}|memjustarg}{806} -\glossaryentry{format.string.escaped@ {\memgloterm{format.string.escaped}}{\memglodesc{(\ref {format.string.escaped})}} {\memgloref{}}|memjustarg}{807} -\glossaryentry{format.parse.ctx@ {\memgloterm{format.parse.ctx}}{\memglodesc{(\ref {format.parse.ctx})}} {\memgloref{}}|memjustarg}{808} -\glossaryentry{format.context@ {\memgloterm{format.context}}{\memglodesc{(\ref {format.context})}} {\memgloref{}}|memjustarg}{810} -\glossaryentry{format.range@ {\memgloterm{format.range}}{\memglodesc{(\ref {format.range})}} {\memgloref{}}|memjustarg}{811} -\glossaryentry{format.range.fmtkind@ {\memgloterm{format.range.fmtkind}}{\memglodesc{(\ref {format.range.fmtkind})}} {\memgloref{}}|memjustarg}{811} -\glossaryentry{format.range.formatter@ {\memgloterm{format.range.formatter}}{\memglodesc{(\ref {format.range.formatter})}} {\memgloref{}}|memjustarg}{811} -\glossaryentry{format.range.fmtdef@ {\memgloterm{format.range.fmtdef}}{\memglodesc{(\ref {format.range.fmtdef})}} {\memgloref{}}|memjustarg}{813} -\glossaryentry{format.range.fmtmap@ {\memgloterm{format.range.fmtmap}}{\memglodesc{(\ref {format.range.fmtmap})}} {\memgloref{}}|memjustarg}{814} -\glossaryentry{format.range.fmtset@ {\memgloterm{format.range.fmtset}}{\memglodesc{(\ref {format.range.fmtset})}} {\memgloref{}}|memjustarg}{815} -\glossaryentry{format.range.fmtstr@ {\memgloterm{format.range.fmtstr}}{\memglodesc{(\ref {format.range.fmtstr})}} {\memgloref{}}|memjustarg}{815} -\glossaryentry{format.arguments@ {\memgloterm{format.arguments}}{\memglodesc{(\ref {format.arguments})}} {\memgloref{}}|memjustarg}{816} -\glossaryentry{format.arg@ {\memgloterm{format.arg}}{\memglodesc{(\ref {format.arg})}} {\memgloref{}}|memjustarg}{816} -\glossaryentry{format.arg.store@ {\memgloterm{format.arg.store}}{\memglodesc{(\ref {format.arg.store})}} {\memgloref{}}|memjustarg}{818} -\glossaryentry{format.args@ {\memgloterm{format.args}}{\memglodesc{(\ref {format.args})}} {\memgloref{}}|memjustarg}{818} -\glossaryentry{format.tuple@ {\memgloterm{format.tuple}}{\memglodesc{(\ref {format.tuple})}} {\memgloref{}}|memjustarg}{819} -\glossaryentry{format.error@ {\memgloterm{format.error}}{\memglodesc{(\ref {format.error})}} {\memgloref{}}|memjustarg}{820} -\glossaryentry{bit@ {\memgloterm{bit}}{\memglodesc{(\ref {bit})}} {\memgloref{}}|memjustarg}{821} -\glossaryentry{bit.general@ {\memgloterm{bit.general}}{\memglodesc{(\ref {bit.general})}} {\memgloref{}}|memjustarg}{821} -\glossaryentry{bit.syn@ {\memgloterm{bit.syn}}{\memglodesc{(\ref {bit.syn})}} {\memgloref{}}|memjustarg}{821} -\glossaryentry{bit.cast@ {\memgloterm{bit.cast}}{\memglodesc{(\ref {bit.cast})}} {\memgloref{}}|memjustarg}{821} -\glossaryentry{bit.byteswap@ {\memgloterm{bit.byteswap}}{\memglodesc{(\ref {bit.byteswap})}} {\memgloref{}}|memjustarg}{822} -\glossaryentry{bit.pow.two@ {\memgloterm{bit.pow.two}}{\memglodesc{(\ref {bit.pow.two})}} {\memgloref{}}|memjustarg}{822} -\glossaryentry{bit.rotate@ {\memgloterm{bit.rotate}}{\memglodesc{(\ref {bit.rotate})}} {\memgloref{}}|memjustarg}{823} -\glossaryentry{bit.count@ {\memgloterm{bit.count}}{\memglodesc{(\ref {bit.count})}} {\memgloref{}}|memjustarg}{823} -\glossaryentry{bit.endian@ {\memgloterm{bit.endian}}{\memglodesc{(\ref {bit.endian})}} {\memgloref{}}|memjustarg}{824} -\glossaryentry{strings@ {\memgloterm{strings}}{\memglodesc{(\ref {strings})}} {\memgloref{}}|memjustarg}{825} -\glossaryentry{strings.general@ {\memgloterm{strings.general}}{\memglodesc{(\ref {strings.general})}} {\memgloref{}}|memjustarg}{825} -\glossaryentry{char.traits@ {\memgloterm{char.traits}}{\memglodesc{(\ref {char.traits})}} {\memgloref{}}|memjustarg}{825} -\glossaryentry{char.traits.general@ {\memgloterm{char.traits.general}}{\memglodesc{(\ref {char.traits.general})}} {\memgloref{}}|memjustarg}{825} -\glossaryentry{char.traits.require@ {\memgloterm{char.traits.require}}{\memglodesc{(\ref {char.traits.require})}} {\memgloref{}}|memjustarg}{825} -\glossaryentry{char.traits.typedefs@ {\memgloterm{char.traits.typedefs}}{\memglodesc{(\ref {char.traits.typedefs})}} {\memgloref{}}|memjustarg}{827} -\glossaryentry{char.traits.specializations@ {\memgloterm{char.traits.specializations}}{\memglodesc{(\ref {char.traits.specializations})}} {\memgloref{}}|memjustarg}{827} -\glossaryentry{char.traits.specializations.general@ {\memgloterm{char.traits.specializations.general}}{\memglodesc{(\ref {char.traits.specializations.general})}} {\memgloref{}}|memjustarg}{827} -\glossaryentry{char.traits.specializations.char@ {\memgloterm{char.traits.specializations.char}}{\memglodesc{(\ref {char.traits.specializations.char})}} {\memgloref{}}|memjustarg}{827} -\glossaryentry{char.traits.specializations.char8.t@ {\memgloterm{char.traits.specializations.char8.t}}{\memglodesc{(\ref {char.traits.specializations.char8.t})}} {\memgloref{}}|memjustarg}{828} -\glossaryentry{char.traits.specializations.char16.t@ {\memgloterm{char.traits.specializations.char16.t}}{\memglodesc{(\ref {char.traits.specializations.char16.t})}} {\memgloref{}}|memjustarg}{828} -\glossaryentry{char.traits.specializations.char32.t@ {\memgloterm{char.traits.specializations.char32.t}}{\memglodesc{(\ref {char.traits.specializations.char32.t})}} {\memgloref{}}|memjustarg}{829} -\glossaryentry{char.traits.specializations.wchar.t@ {\memgloterm{char.traits.specializations.wchar.t}}{\memglodesc{(\ref {char.traits.specializations.wchar.t})}} {\memgloref{}}|memjustarg}{830} -\glossaryentry{string.view@ {\memgloterm{string.view}}{\memglodesc{(\ref {string.view})}} {\memgloref{}}|memjustarg}{830} -\glossaryentry{string.view.general@ {\memgloterm{string.view.general}}{\memglodesc{(\ref {string.view.general})}} {\memgloref{}}|memjustarg}{830} -\glossaryentry{string.view.synop@ {\memgloterm{string.view.synop}}{\memglodesc{(\ref {string.view.synop})}} {\memgloref{}}|memjustarg}{830} -\glossaryentry{string.view.template@ {\memgloterm{string.view.template}}{\memglodesc{(\ref {string.view.template})}} {\memgloref{}}|memjustarg}{831} -\glossaryentry{string.view.template.general@ {\memgloterm{string.view.template.general}}{\memglodesc{(\ref {string.view.template.general})}} {\memgloref{}}|memjustarg}{831} -\glossaryentry{string.view.cons@ {\memgloterm{string.view.cons}}{\memglodesc{(\ref {string.view.cons})}} {\memgloref{}}|memjustarg}{833} -\glossaryentry{string.view.deduct@ {\memgloterm{string.view.deduct}}{\memglodesc{(\ref {string.view.deduct})}} {\memgloref{}}|memjustarg}{834} -\glossaryentry{string.view.iterators@ {\memgloterm{string.view.iterators}}{\memglodesc{(\ref {string.view.iterators})}} {\memgloref{}}|memjustarg}{834} -\glossaryentry{string.view.capacity@ {\memgloterm{string.view.capacity}}{\memglodesc{(\ref {string.view.capacity})}} {\memgloref{}}|memjustarg}{835} -\glossaryentry{string.view.access@ {\memgloterm{string.view.access}}{\memglodesc{(\ref {string.view.access})}} {\memgloref{}}|memjustarg}{835} -\glossaryentry{string.view.modifiers@ {\memgloterm{string.view.modifiers}}{\memglodesc{(\ref {string.view.modifiers})}} {\memgloref{}}|memjustarg}{836} -\glossaryentry{string.view.ops@ {\memgloterm{string.view.ops}}{\memglodesc{(\ref {string.view.ops})}} {\memgloref{}}|memjustarg}{836} -\glossaryentry{string.view.find@ {\memgloterm{string.view.find}}{\memglodesc{(\ref {string.view.find})}} {\memgloref{}}|memjustarg}{837} -\glossaryentry{string.view.comparison@ {\memgloterm{string.view.comparison}}{\memglodesc{(\ref {string.view.comparison})}} {\memgloref{}}|memjustarg}{838} -\glossaryentry{string.view.io@ {\memgloterm{string.view.io}}{\memglodesc{(\ref {string.view.io})}} {\memgloref{}}|memjustarg}{839} -\glossaryentry{string.view.hash@ {\memgloterm{string.view.hash}}{\memglodesc{(\ref {string.view.hash})}} {\memgloref{}}|memjustarg}{840} -\glossaryentry{string.view.literals@ {\memgloterm{string.view.literals}}{\memglodesc{(\ref {string.view.literals})}} {\memgloref{}}|memjustarg}{840} -\glossaryentry{string.classes@ {\memgloterm{string.classes}}{\memglodesc{(\ref {string.classes})}} {\memgloref{}}|memjustarg}{840} -\glossaryentry{string.classes.general@ {\memgloterm{string.classes.general}}{\memglodesc{(\ref {string.classes.general})}} {\memgloref{}}|memjustarg}{840} -\glossaryentry{string.syn@ {\memgloterm{string.syn}}{\memglodesc{(\ref {string.syn})}} {\memgloref{}}|memjustarg}{840} -\glossaryentry{basic.string@ {\memgloterm{basic.string}}{\memglodesc{(\ref {basic.string})}} {\memgloref{}}|memjustarg}{843} -\glossaryentry{basic.string.general@ {\memgloterm{basic.string.general}}{\memglodesc{(\ref {basic.string.general})}} {\memgloref{}}|memjustarg}{843} -\glossaryentry{string.require@ {\memgloterm{string.require}}{\memglodesc{(\ref {string.require})}} {\memgloref{}}|memjustarg}{848} -\glossaryentry{string.cons@ {\memgloterm{string.cons}}{\memglodesc{(\ref {string.cons})}} {\memgloref{}}|memjustarg}{849} -\glossaryentry{string.iterators@ {\memgloterm{string.iterators}}{\memglodesc{(\ref {string.iterators})}} {\memgloref{}}|memjustarg}{851} -\glossaryentry{string.capacity@ {\memgloterm{string.capacity}}{\memglodesc{(\ref {string.capacity})}} {\memgloref{}}|memjustarg}{852} -\glossaryentry{string.access@ {\memgloterm{string.access}}{\memglodesc{(\ref {string.access})}} {\memgloref{}}|memjustarg}{853} -\glossaryentry{string.modifiers@ {\memgloterm{string.modifiers}}{\memglodesc{(\ref {string.modifiers})}} {\memgloref{}}|memjustarg}{853} -\glossaryentry{string.op.append@ {\memgloterm{string.op.append}}{\memglodesc{(\ref {string.op.append})}} {\memgloref{}}|memjustarg}{853} -\glossaryentry{string.append@ {\memgloterm{string.append}}{\memglodesc{(\ref {string.append})}} {\memgloref{}}|memjustarg}{854} -\glossaryentry{string.assign@ {\memgloterm{string.assign}}{\memglodesc{(\ref {string.assign})}} {\memgloref{}}|memjustarg}{855} -\glossaryentry{string.insert@ {\memgloterm{string.insert}}{\memglodesc{(\ref {string.insert})}} {\memgloref{}}|memjustarg}{856} -\glossaryentry{string.erase@ {\memgloterm{string.erase}}{\memglodesc{(\ref {string.erase})}} {\memgloref{}}|memjustarg}{857} -\glossaryentry{string.replace@ {\memgloterm{string.replace}}{\memglodesc{(\ref {string.replace})}} {\memgloref{}}|memjustarg}{858} -\glossaryentry{string.copy@ {\memgloterm{string.copy}}{\memglodesc{(\ref {string.copy})}} {\memgloref{}}|memjustarg}{860} -\glossaryentry{string.swap@ {\memgloterm{string.swap}}{\memglodesc{(\ref {string.swap})}} {\memgloref{}}|memjustarg}{860} -\glossaryentry{string.ops@ {\memgloterm{string.ops}}{\memglodesc{(\ref {string.ops})}} {\memgloref{}}|memjustarg}{860} -\glossaryentry{string.accessors@ {\memgloterm{string.accessors}}{\memglodesc{(\ref {string.accessors})}} {\memgloref{}}|memjustarg}{860} -\glossaryentry{string.find@ {\memgloterm{string.find}}{\memglodesc{(\ref {string.find})}} {\memgloref{}}|memjustarg}{860} -\glossaryentry{string.substr@ {\memgloterm{string.substr}}{\memglodesc{(\ref {string.substr})}} {\memgloref{}}|memjustarg}{861} -\glossaryentry{string.compare@ {\memgloterm{string.compare}}{\memglodesc{(\ref {string.compare})}} {\memgloref{}}|memjustarg}{861} -\glossaryentry{string.starts.with@ {\memgloterm{string.starts.with}}{\memglodesc{(\ref {string.starts.with})}} {\memgloref{}}|memjustarg}{862} -\glossaryentry{string.ends.with@ {\memgloterm{string.ends.with}}{\memglodesc{(\ref {string.ends.with})}} {\memgloref{}}|memjustarg}{862} -\glossaryentry{string.contains@ {\memgloterm{string.contains}}{\memglodesc{(\ref {string.contains})}} {\memgloref{}}|memjustarg}{862} -\glossaryentry{string.nonmembers@ {\memgloterm{string.nonmembers}}{\memglodesc{(\ref {string.nonmembers})}} {\memgloref{}}|memjustarg}{863} -\glossaryentry{string.op.plus@ {\memgloterm{string.op.plus}}{\memglodesc{(\ref {string.op.plus})}} {\memgloref{}}|memjustarg}{863} -\glossaryentry{string.cmp@ {\memgloterm{string.cmp}}{\memglodesc{(\ref {string.cmp})}} {\memgloref{}}|memjustarg}{864} -\glossaryentry{string.special@ {\memgloterm{string.special}}{\memglodesc{(\ref {string.special})}} {\memgloref{}}|memjustarg}{864} -\glossaryentry{string.io@ {\memgloterm{string.io}}{\memglodesc{(\ref {string.io})}} {\memgloref{}}|memjustarg}{865} -\glossaryentry{string.erasure@ {\memgloterm{string.erasure}}{\memglodesc{(\ref {string.erasure})}} {\memgloref{}}|memjustarg}{866} -\glossaryentry{string.conversions@ {\memgloterm{string.conversions}}{\memglodesc{(\ref {string.conversions})}} {\memgloref{}}|memjustarg}{866} -\glossaryentry{basic.string.hash@ {\memgloterm{basic.string.hash}}{\memglodesc{(\ref {basic.string.hash})}} {\memgloref{}}|memjustarg}{867} -\glossaryentry{basic.string.literals@ {\memgloterm{basic.string.literals}}{\memglodesc{(\ref {basic.string.literals})}} {\memgloref{}}|memjustarg}{868} -\glossaryentry{c.strings@ {\memgloterm{c.strings}}{\memglodesc{(\ref {c.strings})}} {\memgloref{}}|memjustarg}{868} -\glossaryentry{cctype.syn@ {\memgloterm{cctype.syn}}{\memglodesc{(\ref {cctype.syn})}} {\memgloref{}}|memjustarg}{868} -\glossaryentry{cwctype.syn@ {\memgloterm{cwctype.syn}}{\memglodesc{(\ref {cwctype.syn})}} {\memgloref{}}|memjustarg}{868} -\glossaryentry{cstring.syn@ {\memgloterm{cstring.syn}}{\memglodesc{(\ref {cstring.syn})}} {\memgloref{}}|memjustarg}{869} -\glossaryentry{cwchar.syn@ {\memgloterm{cwchar.syn}}{\memglodesc{(\ref {cwchar.syn})}} {\memgloref{}}|memjustarg}{870} -\glossaryentry{cuchar.syn@ {\memgloterm{cuchar.syn}}{\memglodesc{(\ref {cuchar.syn})}} {\memgloref{}}|memjustarg}{871} -\glossaryentry{c.mb.wcs@ {\memgloterm{c.mb.wcs}}{\memglodesc{(\ref {c.mb.wcs})}} {\memgloref{}}|memjustarg}{871} -\glossaryentry{containers@ {\memgloterm{containers}}{\memglodesc{(\ref {containers})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{containers.general@ {\memgloterm{containers.general}}{\memglodesc{(\ref {containers.general})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{container.requirements@ {\memgloterm{container.requirements}}{\memglodesc{(\ref {container.requirements})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{container.requirements.pre@ {\memgloterm{container.requirements.pre}}{\memglodesc{(\ref {container.requirements.pre})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{container.gen.reqmts@ {\memgloterm{container.gen.reqmts}}{\memglodesc{(\ref {container.gen.reqmts})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{container.requirements.general@ {\memgloterm{container.requirements.general}}{\memglodesc{(\ref {container.requirements.general})}} {\memgloref{}}|memjustarg}{873} -\glossaryentry{container.reqmts@ {\memgloterm{container.reqmts}}{\memglodesc{(\ref {container.reqmts})}} {\memgloref{}}|memjustarg}{874} -\glossaryentry{container.rev.reqmts@ {\memgloterm{container.rev.reqmts}}{\memglodesc{(\ref {container.rev.reqmts})}} {\memgloref{}}|memjustarg}{877} -\glossaryentry{container.opt.reqmts@ {\memgloterm{container.opt.reqmts}}{\memglodesc{(\ref {container.opt.reqmts})}} {\memgloref{}}|memjustarg}{878} -\glossaryentry{container.alloc.reqmts@ {\memgloterm{container.alloc.reqmts}}{\memglodesc{(\ref {container.alloc.reqmts})}} {\memgloref{}}|memjustarg}{878} -\glossaryentry{container.requirements.dataraces@ {\memgloterm{container.requirements.dataraces}}{\memglodesc{(\ref {container.requirements.dataraces})}} {\memgloref{}}|memjustarg}{880} -\glossaryentry{sequence.reqmts@ {\memgloterm{sequence.reqmts}}{\memglodesc{(\ref {sequence.reqmts})}} {\memgloref{}}|memjustarg}{880} -\glossaryentry{container.node@ {\memgloterm{container.node}}{\memglodesc{(\ref {container.node})}} {\memgloref{}}|memjustarg}{886} -\glossaryentry{container.node.overview@ {\memgloterm{container.node.overview}}{\memglodesc{(\ref {container.node.overview})}} {\memgloref{}}|memjustarg}{886} -\glossaryentry{container.node.cons@ {\memgloterm{container.node.cons}}{\memglodesc{(\ref {container.node.cons})}} {\memgloref{}}|memjustarg}{887} -\glossaryentry{container.node.dtor@ {\memgloterm{container.node.dtor}}{\memglodesc{(\ref {container.node.dtor})}} {\memgloref{}}|memjustarg}{887} -\glossaryentry{container.node.observers@ {\memgloterm{container.node.observers}}{\memglodesc{(\ref {container.node.observers})}} {\memgloref{}}|memjustarg}{887} -\glossaryentry{container.node.modifiers@ {\memgloterm{container.node.modifiers}}{\memglodesc{(\ref {container.node.modifiers})}} {\memgloref{}}|memjustarg}{888} -\glossaryentry{container.insert.return@ {\memgloterm{container.insert.return}}{\memglodesc{(\ref {container.insert.return})}} {\memgloref{}}|memjustarg}{888} -\glossaryentry{associative.reqmts@ {\memgloterm{associative.reqmts}}{\memglodesc{(\ref {associative.reqmts})}} {\memgloref{}}|memjustarg}{888} -\glossaryentry{associative.reqmts.general@ {\memgloterm{associative.reqmts.general}}{\memglodesc{(\ref {associative.reqmts.general})}} {\memgloref{}}|memjustarg}{888} -\glossaryentry{associative.reqmts.except@ {\memgloterm{associative.reqmts.except}}{\memglodesc{(\ref {associative.reqmts.except})}} {\memgloref{}}|memjustarg}{897} -\glossaryentry{unord.req@ {\memgloterm{unord.req}}{\memglodesc{(\ref {unord.req})}} {\memgloref{}}|memjustarg}{897} -\glossaryentry{unord.req.general@ {\memgloterm{unord.req.general}}{\memglodesc{(\ref {unord.req.general})}} {\memgloref{}}|memjustarg}{897} -\glossaryentry{unord.req.except@ {\memgloterm{unord.req.except}}{\memglodesc{(\ref {unord.req.except})}} {\memgloref{}}|memjustarg}{908} -\glossaryentry{sequences@ {\memgloterm{sequences}}{\memglodesc{(\ref {sequences})}} {\memgloref{}}|memjustarg}{908} -\glossaryentry{sequences.general@ {\memgloterm{sequences.general}}{\memglodesc{(\ref {sequences.general})}} {\memgloref{}}|memjustarg}{908} -\glossaryentry{array.syn@ {\memgloterm{array.syn}}{\memglodesc{(\ref {array.syn})}} {\memgloref{}}|memjustarg}{908} -\glossaryentry{deque.syn@ {\memgloterm{deque.syn}}{\memglodesc{(\ref {deque.syn})}} {\memgloref{}}|memjustarg}{909} -\glossaryentry{forward.list.syn@ {\memgloterm{forward.list.syn}}{\memglodesc{(\ref {forward.list.syn})}} {\memgloref{}}|memjustarg}{909} -\glossaryentry{list.syn@ {\memgloterm{list.syn}}{\memglodesc{(\ref {list.syn})}} {\memgloref{}}|memjustarg}{910} -\glossaryentry{vector.syn@ {\memgloterm{vector.syn}}{\memglodesc{(\ref {vector.syn})}} {\memgloref{}}|memjustarg}{910} -\glossaryentry{array@ {\memgloterm{array}}{\memglodesc{(\ref {array})}} {\memgloref{}}|memjustarg}{911} -\glossaryentry{array.overview@ {\memgloterm{array.overview}}{\memglodesc{(\ref {array.overview})}} {\memgloref{}}|memjustarg}{911} -\glossaryentry{array.cons@ {\memgloterm{array.cons}}{\memglodesc{(\ref {array.cons})}} {\memgloref{}}|memjustarg}{912} -\glossaryentry{array.members@ {\memgloterm{array.members}}{\memglodesc{(\ref {array.members})}} {\memgloref{}}|memjustarg}{913} -\glossaryentry{array.special@ {\memgloterm{array.special}}{\memglodesc{(\ref {array.special})}} {\memgloref{}}|memjustarg}{913} -\glossaryentry{array.zero@ {\memgloterm{array.zero}}{\memglodesc{(\ref {array.zero})}} {\memgloref{}}|memjustarg}{913} -\glossaryentry{array.creation@ {\memgloterm{array.creation}}{\memglodesc{(\ref {array.creation})}} {\memgloref{}}|memjustarg}{913} -\glossaryentry{array.tuple@ {\memgloterm{array.tuple}}{\memglodesc{(\ref {array.tuple})}} {\memgloref{}}|memjustarg}{913} -\glossaryentry{deque@ {\memgloterm{deque}}{\memglodesc{(\ref {deque})}} {\memgloref{}}|memjustarg}{914} -\glossaryentry{deque.overview@ {\memgloterm{deque.overview}}{\memglodesc{(\ref {deque.overview})}} {\memgloref{}}|memjustarg}{914} -\glossaryentry{deque.cons@ {\memgloterm{deque.cons}}{\memglodesc{(\ref {deque.cons})}} {\memgloref{}}|memjustarg}{916} -\glossaryentry{deque.capacity@ {\memgloterm{deque.capacity}}{\memglodesc{(\ref {deque.capacity})}} {\memgloref{}}|memjustarg}{916} -\glossaryentry{deque.modifiers@ {\memgloterm{deque.modifiers}}{\memglodesc{(\ref {deque.modifiers})}} {\memgloref{}}|memjustarg}{917} -\glossaryentry{deque.erasure@ {\memgloterm{deque.erasure}}{\memglodesc{(\ref {deque.erasure})}} {\memgloref{}}|memjustarg}{918} -\glossaryentry{forward.list@ {\memgloterm{forward.list}}{\memglodesc{(\ref {forward.list})}} {\memgloref{}}|memjustarg}{918} -\glossaryentry{forward.list.overview@ {\memgloterm{forward.list.overview}}{\memglodesc{(\ref {forward.list.overview})}} {\memgloref{}}|memjustarg}{918} -\glossaryentry{forward.list.cons@ {\memgloterm{forward.list.cons}}{\memglodesc{(\ref {forward.list.cons})}} {\memgloref{}}|memjustarg}{920} -\glossaryentry{forward.list.iter@ {\memgloterm{forward.list.iter}}{\memglodesc{(\ref {forward.list.iter})}} {\memgloref{}}|memjustarg}{921} -\glossaryentry{forward.list.access@ {\memgloterm{forward.list.access}}{\memglodesc{(\ref {forward.list.access})}} {\memgloref{}}|memjustarg}{921} -\glossaryentry{forward.list.modifiers@ {\memgloterm{forward.list.modifiers}}{\memglodesc{(\ref {forward.list.modifiers})}} {\memgloref{}}|memjustarg}{921} -\glossaryentry{forward.list.ops@ {\memgloterm{forward.list.ops}}{\memglodesc{(\ref {forward.list.ops})}} {\memgloref{}}|memjustarg}{923} -\glossaryentry{forward.list.erasure@ {\memgloterm{forward.list.erasure}}{\memglodesc{(\ref {forward.list.erasure})}} {\memgloref{}}|memjustarg}{925} -\glossaryentry{list@ {\memgloterm{list}}{\memglodesc{(\ref {list})}} {\memgloref{}}|memjustarg}{925} -\glossaryentry{list.overview@ {\memgloterm{list.overview}}{\memglodesc{(\ref {list.overview})}} {\memgloref{}}|memjustarg}{925} -\glossaryentry{list.cons@ {\memgloterm{list.cons}}{\memglodesc{(\ref {list.cons})}} {\memgloref{}}|memjustarg}{927} -\glossaryentry{list.capacity@ {\memgloterm{list.capacity}}{\memglodesc{(\ref {list.capacity})}} {\memgloref{}}|memjustarg}{928} -\glossaryentry{list.modifiers@ {\memgloterm{list.modifiers}}{\memglodesc{(\ref {list.modifiers})}} {\memgloref{}}|memjustarg}{928} -\glossaryentry{list.ops@ {\memgloterm{list.ops}}{\memglodesc{(\ref {list.ops})}} {\memgloref{}}|memjustarg}{929} -\glossaryentry{list.erasure@ {\memgloterm{list.erasure}}{\memglodesc{(\ref {list.erasure})}} {\memgloref{}}|memjustarg}{931} -\glossaryentry{vector@ {\memgloterm{vector}}{\memglodesc{(\ref {vector})}} {\memgloref{}}|memjustarg}{931} -\glossaryentry{vector.overview@ {\memgloterm{vector.overview}}{\memglodesc{(\ref {vector.overview})}} {\memgloref{}}|memjustarg}{931} -\glossaryentry{vector.cons@ {\memgloterm{vector.cons}}{\memglodesc{(\ref {vector.cons})}} {\memgloref{}}|memjustarg}{933} -\glossaryentry{vector.capacity@ {\memgloterm{vector.capacity}}{\memglodesc{(\ref {vector.capacity})}} {\memgloref{}}|memjustarg}{934} -\glossaryentry{vector.data@ {\memgloterm{vector.data}}{\memglodesc{(\ref {vector.data})}} {\memgloref{}}|memjustarg}{935} -\glossaryentry{vector.modifiers@ {\memgloterm{vector.modifiers}}{\memglodesc{(\ref {vector.modifiers})}} {\memgloref{}}|memjustarg}{935} -\glossaryentry{vector.erasure@ {\memgloterm{vector.erasure}}{\memglodesc{(\ref {vector.erasure})}} {\memgloref{}}|memjustarg}{935} -\glossaryentry{vector.bool@ {\memgloterm{vector.bool}}{\memglodesc{(\ref {vector.bool})}} {\memgloref{}}|memjustarg}{936} -\glossaryentry{vector.bool.pspc@ {\memgloterm{vector.bool.pspc}}{\memglodesc{(\ref {vector.bool.pspc})}} {\memgloref{}}|memjustarg}{936} -\glossaryentry{vector.bool.fmt@ {\memgloterm{vector.bool.fmt}}{\memglodesc{(\ref {vector.bool.fmt})}} {\memgloref{}}|memjustarg}{938} -\glossaryentry{associative@ {\memgloterm{associative}}{\memglodesc{(\ref {associative})}} {\memgloref{}}|memjustarg}{939} -\glossaryentry{associative.general@ {\memgloterm{associative.general}}{\memglodesc{(\ref {associative.general})}} {\memgloref{}}|memjustarg}{939} -\glossaryentry{associative.map.syn@ {\memgloterm{associative.map.syn}}{\memglodesc{(\ref {associative.map.syn})}} {\memgloref{}}|memjustarg}{939} -\glossaryentry{associative.set.syn@ {\memgloterm{associative.set.syn}}{\memglodesc{(\ref {associative.set.syn})}} {\memgloref{}}|memjustarg}{940} -\glossaryentry{map@ {\memgloterm{map}}{\memglodesc{(\ref {map})}} {\memgloref{}}|memjustarg}{941} -\glossaryentry{map.overview@ {\memgloterm{map.overview}}{\memglodesc{(\ref {map.overview})}} {\memgloref{}}|memjustarg}{941} -\glossaryentry{map.cons@ {\memgloterm{map.cons}}{\memglodesc{(\ref {map.cons})}} {\memgloref{}}|memjustarg}{945} -\glossaryentry{map.access@ {\memgloterm{map.access}}{\memglodesc{(\ref {map.access})}} {\memgloref{}}|memjustarg}{945} -\glossaryentry{map.modifiers@ {\memgloterm{map.modifiers}}{\memglodesc{(\ref {map.modifiers})}} {\memgloref{}}|memjustarg}{945} -\glossaryentry{map.erasure@ {\memgloterm{map.erasure}}{\memglodesc{(\ref {map.erasure})}} {\memgloref{}}|memjustarg}{946} -\glossaryentry{multimap@ {\memgloterm{multimap}}{\memglodesc{(\ref {multimap})}} {\memgloref{}}|memjustarg}{947} -\glossaryentry{multimap.overview@ {\memgloterm{multimap.overview}}{\memglodesc{(\ref {multimap.overview})}} {\memgloref{}}|memjustarg}{947} -\glossaryentry{multimap.cons@ {\memgloterm{multimap.cons}}{\memglodesc{(\ref {multimap.cons})}} {\memgloref{}}|memjustarg}{950} -\glossaryentry{multimap.modifiers@ {\memgloterm{multimap.modifiers}}{\memglodesc{(\ref {multimap.modifiers})}} {\memgloref{}}|memjustarg}{950} -\glossaryentry{multimap.erasure@ {\memgloterm{multimap.erasure}}{\memglodesc{(\ref {multimap.erasure})}} {\memgloref{}}|memjustarg}{950} -\glossaryentry{set@ {\memgloterm{set}}{\memglodesc{(\ref {set})}} {\memgloref{}}|memjustarg}{951} -\glossaryentry{set.overview@ {\memgloterm{set.overview}}{\memglodesc{(\ref {set.overview})}} {\memgloref{}}|memjustarg}{951} -\glossaryentry{set.cons@ {\memgloterm{set.cons}}{\memglodesc{(\ref {set.cons})}} {\memgloref{}}|memjustarg}{954} -\glossaryentry{set.erasure@ {\memgloterm{set.erasure}}{\memglodesc{(\ref {set.erasure})}} {\memgloref{}}|memjustarg}{954} -\glossaryentry{multiset@ {\memgloterm{multiset}}{\memglodesc{(\ref {multiset})}} {\memgloref{}}|memjustarg}{954} -\glossaryentry{multiset.overview@ {\memgloterm{multiset.overview}}{\memglodesc{(\ref {multiset.overview})}} {\memgloref{}}|memjustarg}{954} -\glossaryentry{multiset.cons@ {\memgloterm{multiset.cons}}{\memglodesc{(\ref {multiset.cons})}} {\memgloref{}}|memjustarg}{957} -\glossaryentry{multiset.erasure@ {\memgloterm{multiset.erasure}}{\memglodesc{(\ref {multiset.erasure})}} {\memgloref{}}|memjustarg}{958} -\glossaryentry{unord@ {\memgloterm{unord}}{\memglodesc{(\ref {unord})}} {\memgloref{}}|memjustarg}{958} -\glossaryentry{unord.general@ {\memgloterm{unord.general}}{\memglodesc{(\ref {unord.general})}} {\memgloref{}}|memjustarg}{958} -\glossaryentry{unord.map.syn@ {\memgloterm{unord.map.syn}}{\memglodesc{(\ref {unord.map.syn})}} {\memgloref{}}|memjustarg}{958} -\glossaryentry{unord.set.syn@ {\memgloterm{unord.set.syn}}{\memglodesc{(\ref {unord.set.syn})}} {\memgloref{}}|memjustarg}{959} -\glossaryentry{unord.map@ {\memgloterm{unord.map}}{\memglodesc{(\ref {unord.map})}} {\memgloref{}}|memjustarg}{960} -\glossaryentry{unord.map.overview@ {\memgloterm{unord.map.overview}}{\memglodesc{(\ref {unord.map.overview})}} {\memgloref{}}|memjustarg}{960} -\glossaryentry{unord.map.cnstr@ {\memgloterm{unord.map.cnstr}}{\memglodesc{(\ref {unord.map.cnstr})}} {\memgloref{}}|memjustarg}{965} -\glossaryentry{unord.map.elem@ {\memgloterm{unord.map.elem}}{\memglodesc{(\ref {unord.map.elem})}} {\memgloref{}}|memjustarg}{965} -\glossaryentry{unord.map.modifiers@ {\memgloterm{unord.map.modifiers}}{\memglodesc{(\ref {unord.map.modifiers})}} {\memgloref{}}|memjustarg}{965} -\glossaryentry{unord.map.erasure@ {\memgloterm{unord.map.erasure}}{\memglodesc{(\ref {unord.map.erasure})}} {\memgloref{}}|memjustarg}{967} -\glossaryentry{unord.multimap@ {\memgloterm{unord.multimap}}{\memglodesc{(\ref {unord.multimap})}} {\memgloref{}}|memjustarg}{967} -\glossaryentry{unord.multimap.overview@ {\memgloterm{unord.multimap.overview}}{\memglodesc{(\ref {unord.multimap.overview})}} {\memgloref{}}|memjustarg}{967} -\glossaryentry{unord.multimap.cnstr@ {\memgloterm{unord.multimap.cnstr}}{\memglodesc{(\ref {unord.multimap.cnstr})}} {\memgloref{}}|memjustarg}{971} -\glossaryentry{unord.multimap.modifiers@ {\memgloterm{unord.multimap.modifiers}}{\memglodesc{(\ref {unord.multimap.modifiers})}} {\memgloref{}}|memjustarg}{972} -\glossaryentry{unord.multimap.erasure@ {\memgloterm{unord.multimap.erasure}}{\memglodesc{(\ref {unord.multimap.erasure})}} {\memgloref{}}|memjustarg}{972} -\glossaryentry{unord.set@ {\memgloterm{unord.set}}{\memglodesc{(\ref {unord.set})}} {\memgloref{}}|memjustarg}{972} -\glossaryentry{unord.set.overview@ {\memgloterm{unord.set.overview}}{\memglodesc{(\ref {unord.set.overview})}} {\memgloref{}}|memjustarg}{972} -\glossaryentry{unord.set.cnstr@ {\memgloterm{unord.set.cnstr}}{\memglodesc{(\ref {unord.set.cnstr})}} {\memgloref{}}|memjustarg}{976} -\glossaryentry{unord.set.erasure@ {\memgloterm{unord.set.erasure}}{\memglodesc{(\ref {unord.set.erasure})}} {\memgloref{}}|memjustarg}{977} -\glossaryentry{unord.multiset@ {\memgloterm{unord.multiset}}{\memglodesc{(\ref {unord.multiset})}} {\memgloref{}}|memjustarg}{977} -\glossaryentry{unord.multiset.overview@ {\memgloterm{unord.multiset.overview}}{\memglodesc{(\ref {unord.multiset.overview})}} {\memgloref{}}|memjustarg}{977} -\glossaryentry{unord.multiset.cnstr@ {\memgloterm{unord.multiset.cnstr}}{\memglodesc{(\ref {unord.multiset.cnstr})}} {\memgloref{}}|memjustarg}{981} -\glossaryentry{unord.multiset.erasure@ {\memgloterm{unord.multiset.erasure}}{\memglodesc{(\ref {unord.multiset.erasure})}} {\memgloref{}}|memjustarg}{982} -\glossaryentry{container.adaptors@ {\memgloterm{container.adaptors}}{\memglodesc{(\ref {container.adaptors})}} {\memgloref{}}|memjustarg}{982} -\glossaryentry{container.adaptors.general@ {\memgloterm{container.adaptors.general}}{\memglodesc{(\ref {container.adaptors.general})}} {\memgloref{}}|memjustarg}{982} -\glossaryentry{queue.syn@ {\memgloterm{queue.syn}}{\memglodesc{(\ref {queue.syn})}} {\memgloref{}}|memjustarg}{983} -\glossaryentry{stack.syn@ {\memgloterm{stack.syn}}{\memglodesc{(\ref {stack.syn})}} {\memgloref{}}|memjustarg}{984} -\glossaryentry{flat.map.syn@ {\memgloterm{flat.map.syn}}{\memglodesc{(\ref {flat.map.syn})}} {\memgloref{}}|memjustarg}{984} -\glossaryentry{flat.set.syn@ {\memgloterm{flat.set.syn}}{\memglodesc{(\ref {flat.set.syn})}} {\memgloref{}}|memjustarg}{985} -\glossaryentry{queue@ {\memgloterm{queue}}{\memglodesc{(\ref {queue})}} {\memgloref{}}|memjustarg}{986} -\glossaryentry{queue.defn@ {\memgloterm{queue.defn}}{\memglodesc{(\ref {queue.defn})}} {\memgloref{}}|memjustarg}{986} -\glossaryentry{queue.cons@ {\memgloterm{queue.cons}}{\memglodesc{(\ref {queue.cons})}} {\memgloref{}}|memjustarg}{987} -\glossaryentry{queue.cons.alloc@ {\memgloterm{queue.cons.alloc}}{\memglodesc{(\ref {queue.cons.alloc})}} {\memgloref{}}|memjustarg}{987} -\glossaryentry{queue.mod@ {\memgloterm{queue.mod}}{\memglodesc{(\ref {queue.mod})}} {\memgloref{}}|memjustarg}{988} -\glossaryentry{queue.ops@ {\memgloterm{queue.ops}}{\memglodesc{(\ref {queue.ops})}} {\memgloref{}}|memjustarg}{988} -\glossaryentry{queue.special@ {\memgloterm{queue.special}}{\memglodesc{(\ref {queue.special})}} {\memgloref{}}|memjustarg}{988} -\glossaryentry{priority.queue@ {\memgloterm{priority.queue}}{\memglodesc{(\ref {priority.queue})}} {\memgloref{}}|memjustarg}{988} -\glossaryentry{priqueue.overview@ {\memgloterm{priqueue.overview}}{\memglodesc{(\ref {priqueue.overview})}} {\memgloref{}}|memjustarg}{988} -\glossaryentry{priqueue.cons@ {\memgloterm{priqueue.cons}}{\memglodesc{(\ref {priqueue.cons})}} {\memgloref{}}|memjustarg}{990} -\glossaryentry{priqueue.cons.alloc@ {\memgloterm{priqueue.cons.alloc}}{\memglodesc{(\ref {priqueue.cons.alloc})}} {\memgloref{}}|memjustarg}{991} -\glossaryentry{priqueue.members@ {\memgloterm{priqueue.members}}{\memglodesc{(\ref {priqueue.members})}} {\memgloref{}}|memjustarg}{992} -\glossaryentry{priqueue.special@ {\memgloterm{priqueue.special}}{\memglodesc{(\ref {priqueue.special})}} {\memgloref{}}|memjustarg}{992} -\glossaryentry{stack@ {\memgloterm{stack}}{\memglodesc{(\ref {stack})}} {\memgloref{}}|memjustarg}{992} -\glossaryentry{stack.general@ {\memgloterm{stack.general}}{\memglodesc{(\ref {stack.general})}} {\memgloref{}}|memjustarg}{992} -\glossaryentry{stack.defn@ {\memgloterm{stack.defn}}{\memglodesc{(\ref {stack.defn})}} {\memgloref{}}|memjustarg}{993} -\glossaryentry{stack.cons@ {\memgloterm{stack.cons}}{\memglodesc{(\ref {stack.cons})}} {\memgloref{}}|memjustarg}{994} -\glossaryentry{stack.cons.alloc@ {\memgloterm{stack.cons.alloc}}{\memglodesc{(\ref {stack.cons.alloc})}} {\memgloref{}}|memjustarg}{994} -\glossaryentry{stack.mod@ {\memgloterm{stack.mod}}{\memglodesc{(\ref {stack.mod})}} {\memgloref{}}|memjustarg}{994} -\glossaryentry{stack.ops@ {\memgloterm{stack.ops}}{\memglodesc{(\ref {stack.ops})}} {\memgloref{}}|memjustarg}{995} -\glossaryentry{stack.special@ {\memgloterm{stack.special}}{\memglodesc{(\ref {stack.special})}} {\memgloref{}}|memjustarg}{995} -\glossaryentry{flat.map@ {\memgloterm{flat.map}}{\memglodesc{(\ref {flat.map})}} {\memgloref{}}|memjustarg}{995} -\glossaryentry{flat.map.overview@ {\memgloterm{flat.map.overview}}{\memglodesc{(\ref {flat.map.overview})}} {\memgloref{}}|memjustarg}{995} -\glossaryentry{flat.map.defn@ {\memgloterm{flat.map.defn}}{\memglodesc{(\ref {flat.map.defn})}} {\memgloref{}}|memjustarg}{996} -\glossaryentry{flat.map.cons@ {\memgloterm{flat.map.cons}}{\memglodesc{(\ref {flat.map.cons})}} {\memgloref{}}|memjustarg}{1001} -\glossaryentry{flat.map.capacity@ {\memgloterm{flat.map.capacity}}{\memglodesc{(\ref {flat.map.capacity})}} {\memgloref{}}|memjustarg}{1003} -\glossaryentry{flat.map.access@ {\memgloterm{flat.map.access}}{\memglodesc{(\ref {flat.map.access})}} {\memgloref{}}|memjustarg}{1003} -\glossaryentry{flat.map.modifiers@ {\memgloterm{flat.map.modifiers}}{\memglodesc{(\ref {flat.map.modifiers})}} {\memgloref{}}|memjustarg}{1003} -\glossaryentry{flat.map.erasure@ {\memgloterm{flat.map.erasure}}{\memglodesc{(\ref {flat.map.erasure})}} {\memgloref{}}|memjustarg}{1006} -\glossaryentry{flat.multimap@ {\memgloterm{flat.multimap}}{\memglodesc{(\ref {flat.multimap})}} {\memgloref{}}|memjustarg}{1007} -\glossaryentry{flat.multimap.overview@ {\memgloterm{flat.multimap.overview}}{\memglodesc{(\ref {flat.multimap.overview})}} {\memgloref{}}|memjustarg}{1007} -\glossaryentry{flat.multimap.defn@ {\memgloterm{flat.multimap.defn}}{\memglodesc{(\ref {flat.multimap.defn})}} {\memgloref{}}|memjustarg}{1008} -\glossaryentry{flat.multimap.cons@ {\memgloterm{flat.multimap.cons}}{\memglodesc{(\ref {flat.multimap.cons})}} {\memgloref{}}|memjustarg}{1012} -\glossaryentry{flat.multimap.erasure@ {\memgloterm{flat.multimap.erasure}}{\memglodesc{(\ref {flat.multimap.erasure})}} {\memgloref{}}|memjustarg}{1014} -\glossaryentry{flat.set@ {\memgloterm{flat.set}}{\memglodesc{(\ref {flat.set})}} {\memgloref{}}|memjustarg}{1014} -\glossaryentry{flat.set.overview@ {\memgloterm{flat.set.overview}}{\memglodesc{(\ref {flat.set.overview})}} {\memgloref{}}|memjustarg}{1014} -\glossaryentry{flat.set.defn@ {\memgloterm{flat.set.defn}}{\memglodesc{(\ref {flat.set.defn})}} {\memgloref{}}|memjustarg}{1015} -\glossaryentry{flat.set.cons@ {\memgloterm{flat.set.cons}}{\memglodesc{(\ref {flat.set.cons})}} {\memgloref{}}|memjustarg}{1019} -\glossaryentry{flat.set.modifiers@ {\memgloterm{flat.set.modifiers}}{\memglodesc{(\ref {flat.set.modifiers})}} {\memgloref{}}|memjustarg}{1020} -\glossaryentry{flat.set.erasure@ {\memgloterm{flat.set.erasure}}{\memglodesc{(\ref {flat.set.erasure})}} {\memgloref{}}|memjustarg}{1021} -\glossaryentry{flat.multiset@ {\memgloterm{flat.multiset}}{\memglodesc{(\ref {flat.multiset})}} {\memgloref{}}|memjustarg}{1021} -\glossaryentry{flat.multiset.overview@ {\memgloterm{flat.multiset.overview}}{\memglodesc{(\ref {flat.multiset.overview})}} {\memgloref{}}|memjustarg}{1021} -\glossaryentry{flat.multiset.defn@ {\memgloterm{flat.multiset.defn}}{\memglodesc{(\ref {flat.multiset.defn})}} {\memgloref{}}|memjustarg}{1021} -\glossaryentry{flat.multiset.cons@ {\memgloterm{flat.multiset.cons}}{\memglodesc{(\ref {flat.multiset.cons})}} {\memgloref{}}|memjustarg}{1026} -\glossaryentry{flat.multiset.modifiers@ {\memgloterm{flat.multiset.modifiers}}{\memglodesc{(\ref {flat.multiset.modifiers})}} {\memgloref{}}|memjustarg}{1027} -\glossaryentry{flat.multiset.erasure@ {\memgloterm{flat.multiset.erasure}}{\memglodesc{(\ref {flat.multiset.erasure})}} {\memgloref{}}|memjustarg}{1027} -\glossaryentry{container.adaptors.format@ {\memgloterm{container.adaptors.format}}{\memglodesc{(\ref {container.adaptors.format})}} {\memgloref{}}|memjustarg}{1027} -\glossaryentry{views@ {\memgloterm{views}}{\memglodesc{(\ref {views})}} {\memgloref{}}|memjustarg}{1028} -\glossaryentry{views.general@ {\memgloterm{views.general}}{\memglodesc{(\ref {views.general})}} {\memgloref{}}|memjustarg}{1028} -\glossaryentry{views.contiguous@ {\memgloterm{views.contiguous}}{\memglodesc{(\ref {views.contiguous})}} {\memgloref{}}|memjustarg}{1028} -\glossaryentry{span.syn@ {\memgloterm{span.syn}}{\memglodesc{(\ref {span.syn})}} {\memgloref{}}|memjustarg}{1028} -\glossaryentry{views.span@ {\memgloterm{views.span}}{\memglodesc{(\ref {views.span})}} {\memgloref{}}|memjustarg}{1029} -\glossaryentry{span.overview@ {\memgloterm{span.overview}}{\memglodesc{(\ref {span.overview})}} {\memgloref{}}|memjustarg}{1029} -\glossaryentry{span.cons@ {\memgloterm{span.cons}}{\memglodesc{(\ref {span.cons})}} {\memgloref{}}|memjustarg}{1030} -\glossaryentry{span.deduct@ {\memgloterm{span.deduct}}{\memglodesc{(\ref {span.deduct})}} {\memgloref{}}|memjustarg}{1032} -\glossaryentry{span.sub@ {\memgloterm{span.sub}}{\memglodesc{(\ref {span.sub})}} {\memgloref{}}|memjustarg}{1032} -\glossaryentry{span.obs@ {\memgloterm{span.obs}}{\memglodesc{(\ref {span.obs})}} {\memgloref{}}|memjustarg}{1033} -\glossaryentry{span.elem@ {\memgloterm{span.elem}}{\memglodesc{(\ref {span.elem})}} {\memgloref{}}|memjustarg}{1033} -\glossaryentry{span.iterators@ {\memgloterm{span.iterators}}{\memglodesc{(\ref {span.iterators})}} {\memgloref{}}|memjustarg}{1033} -\glossaryentry{span.objectrep@ {\memgloterm{span.objectrep}}{\memglodesc{(\ref {span.objectrep})}} {\memgloref{}}|memjustarg}{1034} -\glossaryentry{views.multidim@ {\memgloterm{views.multidim}}{\memglodesc{(\ref {views.multidim})}} {\memgloref{}}|memjustarg}{1034} -\glossaryentry{mdspan.overview@ {\memgloterm{mdspan.overview}}{\memglodesc{(\ref {mdspan.overview})}} {\memgloref{}}|memjustarg}{1034} -\glossaryentry{mdspan.syn@ {\memgloterm{mdspan.syn}}{\memglodesc{(\ref {mdspan.syn})}} {\memgloref{}}|memjustarg}{1034} -\glossaryentry{mdspan.extents@ {\memgloterm{mdspan.extents}}{\memglodesc{(\ref {mdspan.extents})}} {\memgloref{}}|memjustarg}{1035} -\glossaryentry{mdspan.extents.overview@ {\memgloterm{mdspan.extents.overview}}{\memglodesc{(\ref {mdspan.extents.overview})}} {\memgloref{}}|memjustarg}{1035} -\glossaryentry{mdspan.extents.expo@ {\memgloterm{mdspan.extents.expo}}{\memglodesc{(\ref {mdspan.extents.expo})}} {\memgloref{}}|memjustarg}{1036} -\glossaryentry{mdspan.extents.cons@ {\memgloterm{mdspan.extents.cons}}{\memglodesc{(\ref {mdspan.extents.cons})}} {\memgloref{}}|memjustarg}{1036} -\glossaryentry{mdspan.extents.obs@ {\memgloterm{mdspan.extents.obs}}{\memglodesc{(\ref {mdspan.extents.obs})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.extents.cmp@ {\memgloterm{mdspan.extents.cmp}}{\memglodesc{(\ref {mdspan.extents.cmp})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.extents.dextents@ {\memgloterm{mdspan.extents.dextents}}{\memglodesc{(\ref {mdspan.extents.dextents})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.layout@ {\memgloterm{mdspan.layout}}{\memglodesc{(\ref {mdspan.layout})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.layout.general@ {\memgloterm{mdspan.layout.general}}{\memglodesc{(\ref {mdspan.layout.general})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.layout.reqmts@ {\memgloterm{mdspan.layout.reqmts}}{\memglodesc{(\ref {mdspan.layout.reqmts})}} {\memgloref{}}|memjustarg}{1038} -\glossaryentry{mdspan.layout.policy.reqmts@ {\memgloterm{mdspan.layout.policy.reqmts}}{\memglodesc{(\ref {mdspan.layout.policy.reqmts})}} {\memgloref{}}|memjustarg}{1040} -\glossaryentry{mdspan.layout.policy.overview@ {\memgloterm{mdspan.layout.policy.overview}}{\memglodesc{(\ref {mdspan.layout.policy.overview})}} {\memgloref{}}|memjustarg}{1040} -\glossaryentry{mdspan.layout.left@ {\memgloterm{mdspan.layout.left}}{\memglodesc{(\ref {mdspan.layout.left})}} {\memgloref{}}|memjustarg}{1040} -\glossaryentry{mdspan.layout.left.overview@ {\memgloterm{mdspan.layout.left.overview}}{\memglodesc{(\ref {mdspan.layout.left.overview})}} {\memgloref{}}|memjustarg}{1040} -\glossaryentry{mdspan.layout.left.cons@ {\memgloterm{mdspan.layout.left.cons}}{\memglodesc{(\ref {mdspan.layout.left.cons})}} {\memgloref{}}|memjustarg}{1041} -\glossaryentry{mdspan.layout.left.obs@ {\memgloterm{mdspan.layout.left.obs}}{\memglodesc{(\ref {mdspan.layout.left.obs})}} {\memgloref{}}|memjustarg}{1042} -\glossaryentry{mdspan.layout.right@ {\memgloterm{mdspan.layout.right}}{\memglodesc{(\ref {mdspan.layout.right})}} {\memgloref{}}|memjustarg}{1042} -\glossaryentry{mdspan.layout.right.overview@ {\memgloterm{mdspan.layout.right.overview}}{\memglodesc{(\ref {mdspan.layout.right.overview})}} {\memgloref{}}|memjustarg}{1042} -\glossaryentry{mdspan.layout.right.cons@ {\memgloterm{mdspan.layout.right.cons}}{\memglodesc{(\ref {mdspan.layout.right.cons})}} {\memgloref{}}|memjustarg}{1043} -\glossaryentry{mdspan.layout.right.obs@ {\memgloterm{mdspan.layout.right.obs}}{\memglodesc{(\ref {mdspan.layout.right.obs})}} {\memgloref{}}|memjustarg}{1044} -\glossaryentry{mdspan.layout.stride@ {\memgloterm{mdspan.layout.stride}}{\memglodesc{(\ref {mdspan.layout.stride})}} {\memgloref{}}|memjustarg}{1044} -\glossaryentry{mdspan.layout.stride.overview@ {\memgloterm{mdspan.layout.stride.overview}}{\memglodesc{(\ref {mdspan.layout.stride.overview})}} {\memgloref{}}|memjustarg}{1044} -\glossaryentry{mdspan.layout.stride.expo@ {\memgloterm{mdspan.layout.stride.expo}}{\memglodesc{(\ref {mdspan.layout.stride.expo})}} {\memgloref{}}|memjustarg}{1045} -\glossaryentry{mdspan.layout.stride.cons@ {\memgloterm{mdspan.layout.stride.cons}}{\memglodesc{(\ref {mdspan.layout.stride.cons})}} {\memgloref{}}|memjustarg}{1046} -\glossaryentry{mdspan.layout.stride.obs@ {\memgloterm{mdspan.layout.stride.obs}}{\memglodesc{(\ref {mdspan.layout.stride.obs})}} {\memgloref{}}|memjustarg}{1047} -\glossaryentry{mdspan.accessor@ {\memgloterm{mdspan.accessor}}{\memglodesc{(\ref {mdspan.accessor})}} {\memgloref{}}|memjustarg}{1048} -\glossaryentry{mdspan.accessor.general@ {\memgloterm{mdspan.accessor.general}}{\memglodesc{(\ref {mdspan.accessor.general})}} {\memgloref{}}|memjustarg}{1048} -\glossaryentry{mdspan.accessor.reqmts@ {\memgloterm{mdspan.accessor.reqmts}}{\memglodesc{(\ref {mdspan.accessor.reqmts})}} {\memgloref{}}|memjustarg}{1048} -\glossaryentry{mdspan.accessor.default@ {\memgloterm{mdspan.accessor.default}}{\memglodesc{(\ref {mdspan.accessor.default})}} {\memgloref{}}|memjustarg}{1049} -\glossaryentry{mdspan.accessor.default.overview@ {\memgloterm{mdspan.accessor.default.overview}}{\memglodesc{(\ref {mdspan.accessor.default.overview})}} {\memgloref{}}|memjustarg}{1049} -\glossaryentry{mdspan.accessor.default.members@ {\memgloterm{mdspan.accessor.default.members}}{\memglodesc{(\ref {mdspan.accessor.default.members})}} {\memgloref{}}|memjustarg}{1049} -\glossaryentry{mdspan.mdspan@ {\memgloterm{mdspan.mdspan}}{\memglodesc{(\ref {mdspan.mdspan})}} {\memgloref{}}|memjustarg}{1049} -\glossaryentry{mdspan.mdspan.overview@ {\memgloterm{mdspan.mdspan.overview}}{\memglodesc{(\ref {mdspan.mdspan.overview})}} {\memgloref{}}|memjustarg}{1049} -\glossaryentry{mdspan.mdspan.cons@ {\memgloterm{mdspan.mdspan.cons}}{\memglodesc{(\ref {mdspan.mdspan.cons})}} {\memgloref{}}|memjustarg}{1052} -\glossaryentry{mdspan.mdspan.members@ {\memgloterm{mdspan.mdspan.members}}{\memglodesc{(\ref {mdspan.mdspan.members})}} {\memgloref{}}|memjustarg}{1054} -\glossaryentry{iterators@ {\memgloterm{iterators}}{\memglodesc{(\ref {iterators})}} {\memgloref{}}|memjustarg}{1055} -\glossaryentry{iterators.general@ {\memgloterm{iterators.general}}{\memglodesc{(\ref {iterators.general})}} {\memgloref{}}|memjustarg}{1055} -\glossaryentry{iterator.synopsis@ {\memgloterm{iterator.synopsis}}{\memglodesc{(\ref {iterator.synopsis})}} {\memgloref{}}|memjustarg}{1055} -\glossaryentry{iterator.requirements@ {\memgloterm{iterator.requirements}}{\memglodesc{(\ref {iterator.requirements})}} {\memgloref{}}|memjustarg}{1063} -\glossaryentry{iterator.requirements.general@ {\memgloterm{iterator.requirements.general}}{\memglodesc{(\ref {iterator.requirements.general})}} {\memgloref{}}|memjustarg}{1063} -\glossaryentry{iterator.assoc.types@ {\memgloterm{iterator.assoc.types}}{\memglodesc{(\ref {iterator.assoc.types})}} {\memgloref{}}|memjustarg}{1064} -\glossaryentry{incrementable.traits@ {\memgloterm{incrementable.traits}}{\memglodesc{(\ref {incrementable.traits})}} {\memgloref{}}|memjustarg}{1064} -\glossaryentry{readable.traits@ {\memgloterm{readable.traits}}{\memglodesc{(\ref {readable.traits})}} {\memgloref{}}|memjustarg}{1065} -\glossaryentry{iterator.traits@ {\memgloterm{iterator.traits}}{\memglodesc{(\ref {iterator.traits})}} {\memgloref{}}|memjustarg}{1066} -\glossaryentry{iterator.cust@ {\memgloterm{iterator.cust}}{\memglodesc{(\ref {iterator.cust})}} {\memgloref{}}|memjustarg}{1068} -\glossaryentry{iterator.cust.move@ {\memgloterm{iterator.cust.move}}{\memglodesc{(\ref {iterator.cust.move})}} {\memgloref{}}|memjustarg}{1068} -\glossaryentry{iterator.cust.swap@ {\memgloterm{iterator.cust.swap}}{\memglodesc{(\ref {iterator.cust.swap})}} {\memgloref{}}|memjustarg}{1069} -\glossaryentry{iterator.concepts@ {\memgloterm{iterator.concepts}}{\memglodesc{(\ref {iterator.concepts})}} {\memgloref{}}|memjustarg}{1069} -\glossaryentry{iterator.concepts.general@ {\memgloterm{iterator.concepts.general}}{\memglodesc{(\ref {iterator.concepts.general})}} {\memgloref{}}|memjustarg}{1069} -\glossaryentry{iterator.concept.readable@ {\memgloterm{iterator.concept.readable}}{\memglodesc{(\ref {iterator.concept.readable})}} {\memgloref{}}|memjustarg}{1070} -\glossaryentry{iterator.concept.writable@ {\memgloterm{iterator.concept.writable}}{\memglodesc{(\ref {iterator.concept.writable})}} {\memgloref{}}|memjustarg}{1070} -\glossaryentry{iterator.concept.winc@ {\memgloterm{iterator.concept.winc}}{\memglodesc{(\ref {iterator.concept.winc})}} {\memgloref{}}|memjustarg}{1071} -\glossaryentry{iterator.concept.inc@ {\memgloterm{iterator.concept.inc}}{\memglodesc{(\ref {iterator.concept.inc})}} {\memgloref{}}|memjustarg}{1072} -\glossaryentry{iterator.concept.iterator@ {\memgloterm{iterator.concept.iterator}}{\memglodesc{(\ref {iterator.concept.iterator})}} {\memgloref{}}|memjustarg}{1073} -\glossaryentry{iterator.concept.sentinel@ {\memgloterm{iterator.concept.sentinel}}{\memglodesc{(\ref {iterator.concept.sentinel})}} {\memgloref{}}|memjustarg}{1073} -\glossaryentry{iterator.concept.sizedsentinel@ {\memgloterm{iterator.concept.sizedsentinel}}{\memglodesc{(\ref {iterator.concept.sizedsentinel})}} {\memgloref{}}|memjustarg}{1073} -\glossaryentry{iterator.concept.input@ {\memgloterm{iterator.concept.input}}{\memglodesc{(\ref {iterator.concept.input})}} {\memgloref{}}|memjustarg}{1074} -\glossaryentry{iterator.concept.output@ {\memgloterm{iterator.concept.output}}{\memglodesc{(\ref {iterator.concept.output})}} {\memgloref{}}|memjustarg}{1074} -\glossaryentry{iterator.concept.forward@ {\memgloterm{iterator.concept.forward}}{\memglodesc{(\ref {iterator.concept.forward})}} {\memgloref{}}|memjustarg}{1074} -\glossaryentry{iterator.concept.bidir@ {\memgloterm{iterator.concept.bidir}}{\memglodesc{(\ref {iterator.concept.bidir})}} {\memgloref{}}|memjustarg}{1075} -\glossaryentry{iterator.concept.random.access@ {\memgloterm{iterator.concept.random.access}}{\memglodesc{(\ref {iterator.concept.random.access})}} {\memgloref{}}|memjustarg}{1075} -\glossaryentry{iterator.concept.contiguous@ {\memgloterm{iterator.concept.contiguous}}{\memglodesc{(\ref {iterator.concept.contiguous})}} {\memgloref{}}|memjustarg}{1076} -\glossaryentry{iterator.cpp17@ {\memgloterm{iterator.cpp17}}{\memglodesc{(\ref {iterator.cpp17})}} {\memgloref{}}|memjustarg}{1076} -\glossaryentry{iterator.cpp17.general@ {\memgloterm{iterator.cpp17.general}}{\memglodesc{(\ref {iterator.cpp17.general})}} {\memgloref{}}|memjustarg}{1076} -\glossaryentry{iterator.iterators@ {\memgloterm{iterator.iterators}}{\memglodesc{(\ref {iterator.iterators})}} {\memgloref{}}|memjustarg}{1076} -\glossaryentry{input.iterators@ {\memgloterm{input.iterators}}{\memglodesc{(\ref {input.iterators})}} {\memgloref{}}|memjustarg}{1076} -\glossaryentry{output.iterators@ {\memgloterm{output.iterators}}{\memglodesc{(\ref {output.iterators})}} {\memgloref{}}|memjustarg}{1078} -\glossaryentry{forward.iterators@ {\memgloterm{forward.iterators}}{\memglodesc{(\ref {forward.iterators})}} {\memgloref{}}|memjustarg}{1078} -\glossaryentry{bidirectional.iterators@ {\memgloterm{bidirectional.iterators}}{\memglodesc{(\ref {bidirectional.iterators})}} {\memgloref{}}|memjustarg}{1079} -\glossaryentry{random.access.iterators@ {\memgloterm{random.access.iterators}}{\memglodesc{(\ref {random.access.iterators})}} {\memgloref{}}|memjustarg}{1079} -\glossaryentry{indirectcallable@ {\memgloterm{indirectcallable}}{\memglodesc{(\ref {indirectcallable})}} {\memgloref{}}|memjustarg}{1080} -\glossaryentry{indirectcallable.general@ {\memgloterm{indirectcallable.general}}{\memglodesc{(\ref {indirectcallable.general})}} {\memgloref{}}|memjustarg}{1080} -\glossaryentry{indirectcallable.traits@ {\memgloterm{indirectcallable.traits}}{\memglodesc{(\ref {indirectcallable.traits})}} {\memgloref{}}|memjustarg}{1080} -\glossaryentry{indirectcallable.indirectinvocable@ {\memgloterm{indirectcallable.indirectinvocable}}{\memglodesc{(\ref {indirectcallable.indirectinvocable})}} {\memgloref{}}|memjustarg}{1081} -\glossaryentry{projected@ {\memgloterm{projected}}{\memglodesc{(\ref {projected})}} {\memgloref{}}|memjustarg}{1082} -\glossaryentry{alg.req@ {\memgloterm{alg.req}}{\memglodesc{(\ref {alg.req})}} {\memgloref{}}|memjustarg}{1082} -\glossaryentry{alg.req.general@ {\memgloterm{alg.req.general}}{\memglodesc{(\ref {alg.req.general})}} {\memgloref{}}|memjustarg}{1082} -\glossaryentry{alg.req.ind.move@ {\memgloterm{alg.req.ind.move}}{\memglodesc{(\ref {alg.req.ind.move})}} {\memgloref{}}|memjustarg}{1082} -\glossaryentry{alg.req.ind.copy@ {\memgloterm{alg.req.ind.copy}}{\memglodesc{(\ref {alg.req.ind.copy})}} {\memgloref{}}|memjustarg}{1082} -\glossaryentry{alg.req.ind.swap@ {\memgloterm{alg.req.ind.swap}}{\memglodesc{(\ref {alg.req.ind.swap})}} {\memgloref{}}|memjustarg}{1083} -\glossaryentry{alg.req.ind.cmp@ {\memgloterm{alg.req.ind.cmp}}{\memglodesc{(\ref {alg.req.ind.cmp})}} {\memgloref{}}|memjustarg}{1083} -\glossaryentry{alg.req.permutable@ {\memgloterm{alg.req.permutable}}{\memglodesc{(\ref {alg.req.permutable})}} {\memgloref{}}|memjustarg}{1083} -\glossaryentry{alg.req.mergeable@ {\memgloterm{alg.req.mergeable}}{\memglodesc{(\ref {alg.req.mergeable})}} {\memgloref{}}|memjustarg}{1083} -\glossaryentry{alg.req.sortable@ {\memgloterm{alg.req.sortable}}{\memglodesc{(\ref {alg.req.sortable})}} {\memgloref{}}|memjustarg}{1084} -\glossaryentry{iterator.primitives@ {\memgloterm{iterator.primitives}}{\memglodesc{(\ref {iterator.primitives})}} {\memgloref{}}|memjustarg}{1084} -\glossaryentry{iterator.primitives.general@ {\memgloterm{iterator.primitives.general}}{\memglodesc{(\ref {iterator.primitives.general})}} {\memgloref{}}|memjustarg}{1084} -\glossaryentry{std.iterator.tags@ {\memgloterm{std.iterator.tags}}{\memglodesc{(\ref {std.iterator.tags})}} {\memgloref{}}|memjustarg}{1084} -\glossaryentry{iterator.operations@ {\memgloterm{iterator.operations}}{\memglodesc{(\ref {iterator.operations})}} {\memgloref{}}|memjustarg}{1085} -\glossaryentry{range.iter.ops@ {\memgloterm{range.iter.ops}}{\memglodesc{(\ref {range.iter.ops})}} {\memgloref{}}|memjustarg}{1085} -\glossaryentry{range.iter.ops.general@ {\memgloterm{range.iter.ops.general}}{\memglodesc{(\ref {range.iter.ops.general})}} {\memgloref{}}|memjustarg}{1085} -\glossaryentry{range.iter.op.advance@ {\memgloterm{range.iter.op.advance}}{\memglodesc{(\ref {range.iter.op.advance})}} {\memgloref{}}|memjustarg}{1086} -\glossaryentry{range.iter.op.distance@ {\memgloterm{range.iter.op.distance}}{\memglodesc{(\ref {range.iter.op.distance})}} {\memgloref{}}|memjustarg}{1086} -\glossaryentry{range.iter.op.next@ {\memgloterm{range.iter.op.next}}{\memglodesc{(\ref {range.iter.op.next})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{range.iter.op.prev@ {\memgloterm{range.iter.op.prev}}{\memglodesc{(\ref {range.iter.op.prev})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{predef.iterators@ {\memgloterm{predef.iterators}}{\memglodesc{(\ref {predef.iterators})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{reverse.iterators@ {\memgloterm{reverse.iterators}}{\memglodesc{(\ref {reverse.iterators})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{reverse.iterators.general@ {\memgloterm{reverse.iterators.general}}{\memglodesc{(\ref {reverse.iterators.general})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{reverse.iterator@ {\memgloterm{reverse.iterator}}{\memglodesc{(\ref {reverse.iterator})}} {\memgloref{}}|memjustarg}{1087} -\glossaryentry{reverse.iter.requirements@ {\memgloterm{reverse.iter.requirements}}{\memglodesc{(\ref {reverse.iter.requirements})}} {\memgloref{}}|memjustarg}{1088} -\glossaryentry{reverse.iter.cons@ {\memgloterm{reverse.iter.cons}}{\memglodesc{(\ref {reverse.iter.cons})}} {\memgloref{}}|memjustarg}{1088} -\glossaryentry{reverse.iter.conv@ {\memgloterm{reverse.iter.conv}}{\memglodesc{(\ref {reverse.iter.conv})}} {\memgloref{}}|memjustarg}{1089} -\glossaryentry{reverse.iter.elem@ {\memgloterm{reverse.iter.elem}}{\memglodesc{(\ref {reverse.iter.elem})}} {\memgloref{}}|memjustarg}{1089} -\glossaryentry{reverse.iter.nav@ {\memgloterm{reverse.iter.nav}}{\memglodesc{(\ref {reverse.iter.nav})}} {\memgloref{}}|memjustarg}{1089} -\glossaryentry{reverse.iter.cmp@ {\memgloterm{reverse.iter.cmp}}{\memglodesc{(\ref {reverse.iter.cmp})}} {\memgloref{}}|memjustarg}{1090} -\glossaryentry{reverse.iter.nonmember@ {\memgloterm{reverse.iter.nonmember}}{\memglodesc{(\ref {reverse.iter.nonmember})}} {\memgloref{}}|memjustarg}{1091} -\glossaryentry{insert.iterators@ {\memgloterm{insert.iterators}}{\memglodesc{(\ref {insert.iterators})}} {\memgloref{}}|memjustarg}{1091} -\glossaryentry{insert.iterators.general@ {\memgloterm{insert.iterators.general}}{\memglodesc{(\ref {insert.iterators.general})}} {\memgloref{}}|memjustarg}{1091} -\glossaryentry{back.insert.iterator@ {\memgloterm{back.insert.iterator}}{\memglodesc{(\ref {back.insert.iterator})}} {\memgloref{}}|memjustarg}{1092} -\glossaryentry{back.insert.iter.ops@ {\memgloterm{back.insert.iter.ops}}{\memglodesc{(\ref {back.insert.iter.ops})}} {\memgloref{}}|memjustarg}{1092} -\glossaryentry{back.inserter@ {\memgloterm{back.inserter}}{\memglodesc{(\ref {back.inserter})}} {\memgloref{}}|memjustarg}{1093} -\glossaryentry{front.insert.iterator@ {\memgloterm{front.insert.iterator}}{\memglodesc{(\ref {front.insert.iterator})}} {\memgloref{}}|memjustarg}{1093} -\glossaryentry{front.insert.iter.ops@ {\memgloterm{front.insert.iter.ops}}{\memglodesc{(\ref {front.insert.iter.ops})}} {\memgloref{}}|memjustarg}{1093} -\glossaryentry{front.inserter@ {\memgloterm{front.inserter}}{\memglodesc{(\ref {front.inserter})}} {\memgloref{}}|memjustarg}{1093} -\glossaryentry{insert.iterator@ {\memgloterm{insert.iterator}}{\memglodesc{(\ref {insert.iterator})}} {\memgloref{}}|memjustarg}{1094} -\glossaryentry{insert.iter.ops@ {\memgloterm{insert.iter.ops}}{\memglodesc{(\ref {insert.iter.ops})}} {\memgloref{}}|memjustarg}{1094} -\glossaryentry{inserter@ {\memgloterm{inserter}}{\memglodesc{(\ref {inserter})}} {\memgloref{}}|memjustarg}{1094} -\glossaryentry{const.iterators@ {\memgloterm{const.iterators}}{\memglodesc{(\ref {const.iterators})}} {\memgloref{}}|memjustarg}{1095} -\glossaryentry{const.iterators.general@ {\memgloterm{const.iterators.general}}{\memglodesc{(\ref {const.iterators.general})}} {\memgloref{}}|memjustarg}{1095} -\glossaryentry{const.iterators.alias@ {\memgloterm{const.iterators.alias}}{\memglodesc{(\ref {const.iterators.alias})}} {\memgloref{}}|memjustarg}{1095} -\glossaryentry{const.iterators.iterator@ {\memgloterm{const.iterators.iterator}}{\memglodesc{(\ref {const.iterators.iterator})}} {\memgloref{}}|memjustarg}{1095} -\glossaryentry{const.iterators.types@ {\memgloterm{const.iterators.types}}{\memglodesc{(\ref {const.iterators.types})}} {\memgloref{}}|memjustarg}{1097} -\glossaryentry{const.iterators.ops@ {\memgloterm{const.iterators.ops}}{\memglodesc{(\ref {const.iterators.ops})}} {\memgloref{}}|memjustarg}{1097} -\glossaryentry{move.iterators@ {\memgloterm{move.iterators}}{\memglodesc{(\ref {move.iterators})}} {\memgloref{}}|memjustarg}{1100} -\glossaryentry{move.iterators.general@ {\memgloterm{move.iterators.general}}{\memglodesc{(\ref {move.iterators.general})}} {\memgloref{}}|memjustarg}{1100} -\glossaryentry{move.iterator@ {\memgloterm{move.iterator}}{\memglodesc{(\ref {move.iterator})}} {\memgloref{}}|memjustarg}{1100} -\glossaryentry{move.iter.requirements@ {\memgloterm{move.iter.requirements}}{\memglodesc{(\ref {move.iter.requirements})}} {\memgloref{}}|memjustarg}{1101} -\glossaryentry{move.iter.cons@ {\memgloterm{move.iter.cons}}{\memglodesc{(\ref {move.iter.cons})}} {\memgloref{}}|memjustarg}{1101} -\glossaryentry{move.iter.op.conv@ {\memgloterm{move.iter.op.conv}}{\memglodesc{(\ref {move.iter.op.conv})}} {\memgloref{}}|memjustarg}{1101} -\glossaryentry{move.iter.elem@ {\memgloterm{move.iter.elem}}{\memglodesc{(\ref {move.iter.elem})}} {\memgloref{}}|memjustarg}{1102} -\glossaryentry{move.iter.nav@ {\memgloterm{move.iter.nav}}{\memglodesc{(\ref {move.iter.nav})}} {\memgloref{}}|memjustarg}{1102} -\glossaryentry{move.iter.op.comp@ {\memgloterm{move.iter.op.comp}}{\memglodesc{(\ref {move.iter.op.comp})}} {\memgloref{}}|memjustarg}{1102} -\glossaryentry{move.iter.nonmember@ {\memgloterm{move.iter.nonmember}}{\memglodesc{(\ref {move.iter.nonmember})}} {\memgloref{}}|memjustarg}{1103} -\glossaryentry{move.sentinel@ {\memgloterm{move.sentinel}}{\memglodesc{(\ref {move.sentinel})}} {\memgloref{}}|memjustarg}{1104} -\glossaryentry{move.sent.ops@ {\memgloterm{move.sent.ops}}{\memglodesc{(\ref {move.sent.ops})}} {\memgloref{}}|memjustarg}{1104} -\glossaryentry{iterators.common@ {\memgloterm{iterators.common}}{\memglodesc{(\ref {iterators.common})}} {\memgloref{}}|memjustarg}{1105} -\glossaryentry{common.iterator@ {\memgloterm{common.iterator}}{\memglodesc{(\ref {common.iterator})}} {\memgloref{}}|memjustarg}{1105} -\glossaryentry{common.iter.types@ {\memgloterm{common.iter.types}}{\memglodesc{(\ref {common.iter.types})}} {\memgloref{}}|memjustarg}{1106} -\glossaryentry{common.iter.const@ {\memgloterm{common.iter.const}}{\memglodesc{(\ref {common.iter.const})}} {\memgloref{}}|memjustarg}{1106} -\glossaryentry{common.iter.access@ {\memgloterm{common.iter.access}}{\memglodesc{(\ref {common.iter.access})}} {\memgloref{}}|memjustarg}{1107} -\glossaryentry{common.iter.nav@ {\memgloterm{common.iter.nav}}{\memglodesc{(\ref {common.iter.nav})}} {\memgloref{}}|memjustarg}{1107} -\glossaryentry{common.iter.cmp@ {\memgloterm{common.iter.cmp}}{\memglodesc{(\ref {common.iter.cmp})}} {\memgloref{}}|memjustarg}{1108} -\glossaryentry{common.iter.cust@ {\memgloterm{common.iter.cust}}{\memglodesc{(\ref {common.iter.cust})}} {\memgloref{}}|memjustarg}{1108} -\glossaryentry{default.sentinel@ {\memgloterm{default.sentinel}}{\memglodesc{(\ref {default.sentinel})}} {\memgloref{}}|memjustarg}{1109} -\glossaryentry{iterators.counted@ {\memgloterm{iterators.counted}}{\memglodesc{(\ref {iterators.counted})}} {\memgloref{}}|memjustarg}{1109} -\glossaryentry{counted.iterator@ {\memgloterm{counted.iterator}}{\memglodesc{(\ref {counted.iterator})}} {\memgloref{}}|memjustarg}{1109} -\glossaryentry{counted.iter.const@ {\memgloterm{counted.iter.const}}{\memglodesc{(\ref {counted.iter.const})}} {\memgloref{}}|memjustarg}{1110} -\glossaryentry{counted.iter.access@ {\memgloterm{counted.iter.access}}{\memglodesc{(\ref {counted.iter.access})}} {\memgloref{}}|memjustarg}{1111} -\glossaryentry{counted.iter.elem@ {\memgloterm{counted.iter.elem}}{\memglodesc{(\ref {counted.iter.elem})}} {\memgloref{}}|memjustarg}{1111} -\glossaryentry{counted.iter.nav@ {\memgloterm{counted.iter.nav}}{\memglodesc{(\ref {counted.iter.nav})}} {\memgloref{}}|memjustarg}{1111} -\glossaryentry{counted.iter.cmp@ {\memgloterm{counted.iter.cmp}}{\memglodesc{(\ref {counted.iter.cmp})}} {\memgloref{}}|memjustarg}{1113} -\glossaryentry{counted.iter.cust@ {\memgloterm{counted.iter.cust}}{\memglodesc{(\ref {counted.iter.cust})}} {\memgloref{}}|memjustarg}{1113} -\glossaryentry{unreachable.sentinel@ {\memgloterm{unreachable.sentinel}}{\memglodesc{(\ref {unreachable.sentinel})}} {\memgloref{}}|memjustarg}{1113} -\glossaryentry{stream.iterators@ {\memgloterm{stream.iterators}}{\memglodesc{(\ref {stream.iterators})}} {\memgloref{}}|memjustarg}{1114} -\glossaryentry{stream.iterators.general@ {\memgloterm{stream.iterators.general}}{\memglodesc{(\ref {stream.iterators.general})}} {\memgloref{}}|memjustarg}{1114} -\glossaryentry{istream.iterator@ {\memgloterm{istream.iterator}}{\memglodesc{(\ref {istream.iterator})}} {\memgloref{}}|memjustarg}{1114} -\glossaryentry{istream.iterator.general@ {\memgloterm{istream.iterator.general}}{\memglodesc{(\ref {istream.iterator.general})}} {\memgloref{}}|memjustarg}{1114} -\glossaryentry{istream.iterator.cons@ {\memgloterm{istream.iterator.cons}}{\memglodesc{(\ref {istream.iterator.cons})}} {\memgloref{}}|memjustarg}{1114} -\glossaryentry{istream.iterator.ops@ {\memgloterm{istream.iterator.ops}}{\memglodesc{(\ref {istream.iterator.ops})}} {\memgloref{}}|memjustarg}{1115} -\glossaryentry{ostream.iterator@ {\memgloterm{ostream.iterator}}{\memglodesc{(\ref {ostream.iterator})}} {\memgloref{}}|memjustarg}{1115} -\glossaryentry{ostream.iterator.general@ {\memgloterm{ostream.iterator.general}}{\memglodesc{(\ref {ostream.iterator.general})}} {\memgloref{}}|memjustarg}{1115} -\glossaryentry{ostream.iterator.cons.des@ {\memgloterm{ostream.iterator.cons.des}}{\memglodesc{(\ref {ostream.iterator.cons.des})}} {\memgloref{}}|memjustarg}{1116} -\glossaryentry{ostream.iterator.ops@ {\memgloterm{ostream.iterator.ops}}{\memglodesc{(\ref {ostream.iterator.ops})}} {\memgloref{}}|memjustarg}{1116} -\glossaryentry{istreambuf.iterator@ {\memgloterm{istreambuf.iterator}}{\memglodesc{(\ref {istreambuf.iterator})}} {\memgloref{}}|memjustarg}{1116} -\glossaryentry{istreambuf.iterator.general@ {\memgloterm{istreambuf.iterator.general}}{\memglodesc{(\ref {istreambuf.iterator.general})}} {\memgloref{}}|memjustarg}{1116} -\glossaryentry{istreambuf.iterator.proxy@ {\memgloterm{istreambuf.iterator.proxy}}{\memglodesc{(\ref {istreambuf.iterator.proxy})}} {\memgloref{}}|memjustarg}{1117} -\glossaryentry{istreambuf.iterator.cons@ {\memgloterm{istreambuf.iterator.cons}}{\memglodesc{(\ref {istreambuf.iterator.cons})}} {\memgloref{}}|memjustarg}{1117} -\glossaryentry{istreambuf.iterator.ops@ {\memgloterm{istreambuf.iterator.ops}}{\memglodesc{(\ref {istreambuf.iterator.ops})}} {\memgloref{}}|memjustarg}{1118} -\glossaryentry{ostreambuf.iterator@ {\memgloterm{ostreambuf.iterator}}{\memglodesc{(\ref {ostreambuf.iterator})}} {\memgloref{}}|memjustarg}{1118} -\glossaryentry{ostreambuf.iterator.general@ {\memgloterm{ostreambuf.iterator.general}}{\memglodesc{(\ref {ostreambuf.iterator.general})}} {\memgloref{}}|memjustarg}{1118} -\glossaryentry{ostreambuf.iter.cons@ {\memgloterm{ostreambuf.iter.cons}}{\memglodesc{(\ref {ostreambuf.iter.cons})}} {\memgloref{}}|memjustarg}{1119} -\glossaryentry{ostreambuf.iter.ops@ {\memgloterm{ostreambuf.iter.ops}}{\memglodesc{(\ref {ostreambuf.iter.ops})}} {\memgloref{}}|memjustarg}{1119} -\glossaryentry{iterator.range@ {\memgloterm{iterator.range}}{\memglodesc{(\ref {iterator.range})}} {\memgloref{}}|memjustarg}{1119} -\glossaryentry{ranges@ {\memgloterm{ranges}}{\memglodesc{(\ref {ranges})}} {\memgloref{}}|memjustarg}{1122} -\glossaryentry{ranges.general@ {\memgloterm{ranges.general}}{\memglodesc{(\ref {ranges.general})}} {\memgloref{}}|memjustarg}{1122} -\glossaryentry{ranges.syn@ {\memgloterm{ranges.syn}}{\memglodesc{(\ref {ranges.syn})}} {\memgloref{}}|memjustarg}{1122} -\glossaryentry{range.access@ {\memgloterm{range.access}}{\memglodesc{(\ref {range.access})}} {\memgloref{}}|memjustarg}{1131} -\glossaryentry{range.access.general@ {\memgloterm{range.access.general}}{\memglodesc{(\ref {range.access.general})}} {\memgloref{}}|memjustarg}{1131} -\glossaryentry{range.access.begin@ {\memgloterm{range.access.begin}}{\memglodesc{(\ref {range.access.begin})}} {\memgloref{}}|memjustarg}{1131} -\glossaryentry{range.access.end@ {\memgloterm{range.access.end}}{\memglodesc{(\ref {range.access.end})}} {\memgloref{}}|memjustarg}{1131} -\glossaryentry{range.access.cbegin@ {\memgloterm{range.access.cbegin}}{\memglodesc{(\ref {range.access.cbegin})}} {\memgloref{}}|memjustarg}{1132} -\glossaryentry{range.access.cend@ {\memgloterm{range.access.cend}}{\memglodesc{(\ref {range.access.cend})}} {\memgloref{}}|memjustarg}{1132} -\glossaryentry{range.access.rbegin@ {\memgloterm{range.access.rbegin}}{\memglodesc{(\ref {range.access.rbegin})}} {\memgloref{}}|memjustarg}{1132} -\glossaryentry{range.access.rend@ {\memgloterm{range.access.rend}}{\memglodesc{(\ref {range.access.rend})}} {\memgloref{}}|memjustarg}{1132} -\glossaryentry{range.access.crbegin@ {\memgloterm{range.access.crbegin}}{\memglodesc{(\ref {range.access.crbegin})}} {\memgloref{}}|memjustarg}{1133} -\glossaryentry{range.access.crend@ {\memgloterm{range.access.crend}}{\memglodesc{(\ref {range.access.crend})}} {\memgloref{}}|memjustarg}{1133} -\glossaryentry{range.prim.size@ {\memgloterm{range.prim.size}}{\memglodesc{(\ref {range.prim.size})}} {\memgloref{}}|memjustarg}{1133} -\glossaryentry{range.prim.ssize@ {\memgloterm{range.prim.ssize}}{\memglodesc{(\ref {range.prim.ssize})}} {\memgloref{}}|memjustarg}{1134} -\glossaryentry{range.prim.empty@ {\memgloterm{range.prim.empty}}{\memglodesc{(\ref {range.prim.empty})}} {\memgloref{}}|memjustarg}{1134} -\glossaryentry{range.prim.data@ {\memgloterm{range.prim.data}}{\memglodesc{(\ref {range.prim.data})}} {\memgloref{}}|memjustarg}{1134} -\glossaryentry{range.prim.cdata@ {\memgloterm{range.prim.cdata}}{\memglodesc{(\ref {range.prim.cdata})}} {\memgloref{}}|memjustarg}{1134} -\glossaryentry{range.req@ {\memgloterm{range.req}}{\memglodesc{(\ref {range.req})}} {\memgloref{}}|memjustarg}{1135} -\glossaryentry{range.req.general@ {\memgloterm{range.req.general}}{\memglodesc{(\ref {range.req.general})}} {\memgloref{}}|memjustarg}{1135} -\glossaryentry{range.range@ {\memgloterm{range.range}}{\memglodesc{(\ref {range.range})}} {\memgloref{}}|memjustarg}{1135} -\glossaryentry{range.sized@ {\memgloterm{range.sized}}{\memglodesc{(\ref {range.sized})}} {\memgloref{}}|memjustarg}{1136} -\glossaryentry{range.view@ {\memgloterm{range.view}}{\memglodesc{(\ref {range.view})}} {\memgloref{}}|memjustarg}{1136} -\glossaryentry{range.refinements@ {\memgloterm{range.refinements}}{\memglodesc{(\ref {range.refinements})}} {\memgloref{}}|memjustarg}{1137} -\glossaryentry{range.utility@ {\memgloterm{range.utility}}{\memglodesc{(\ref {range.utility})}} {\memgloref{}}|memjustarg}{1138} -\glossaryentry{range.utility.general@ {\memgloterm{range.utility.general}}{\memglodesc{(\ref {range.utility.general})}} {\memgloref{}}|memjustarg}{1138} -\glossaryentry{range.utility.helpers@ {\memgloterm{range.utility.helpers}}{\memglodesc{(\ref {range.utility.helpers})}} {\memgloref{}}|memjustarg}{1138} -\glossaryentry{view.interface@ {\memgloterm{view.interface}}{\memglodesc{(\ref {view.interface})}} {\memgloref{}}|memjustarg}{1138} -\glossaryentry{view.interface.general@ {\memgloterm{view.interface.general}}{\memglodesc{(\ref {view.interface.general})}} {\memgloref{}}|memjustarg}{1138} -\glossaryentry{view.interface.members@ {\memgloterm{view.interface.members}}{\memglodesc{(\ref {view.interface.members})}} {\memgloref{}}|memjustarg}{1140} -\glossaryentry{range.subrange@ {\memgloterm{range.subrange}}{\memglodesc{(\ref {range.subrange})}} {\memgloref{}}|memjustarg}{1140} -\glossaryentry{range.subrange.general@ {\memgloterm{range.subrange.general}}{\memglodesc{(\ref {range.subrange.general})}} {\memgloref{}}|memjustarg}{1140} -\glossaryentry{range.subrange.ctor@ {\memgloterm{range.subrange.ctor}}{\memglodesc{(\ref {range.subrange.ctor})}} {\memgloref{}}|memjustarg}{1141} -\glossaryentry{range.subrange.access@ {\memgloterm{range.subrange.access}}{\memglodesc{(\ref {range.subrange.access})}} {\memgloref{}}|memjustarg}{1142} -\glossaryentry{range.dangling@ {\memgloterm{range.dangling}}{\memglodesc{(\ref {range.dangling})}} {\memgloref{}}|memjustarg}{1143} -\glossaryentry{range.elementsof@ {\memgloterm{range.elementsof}}{\memglodesc{(\ref {range.elementsof})}} {\memgloref{}}|memjustarg}{1144} -\glossaryentry{range.utility.conv@ {\memgloterm{range.utility.conv}}{\memglodesc{(\ref {range.utility.conv})}} {\memgloref{}}|memjustarg}{1144} -\glossaryentry{range.utility.conv.general@ {\memgloterm{range.utility.conv.general}}{\memglodesc{(\ref {range.utility.conv.general})}} {\memgloref{}}|memjustarg}{1144} -\glossaryentry{range.utility.conv.to@ {\memgloterm{range.utility.conv.to}}{\memglodesc{(\ref {range.utility.conv.to})}} {\memgloref{}}|memjustarg}{1145} -\glossaryentry{range.utility.conv.adaptors@ {\memgloterm{range.utility.conv.adaptors}}{\memglodesc{(\ref {range.utility.conv.adaptors})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.factories@ {\memgloterm{range.factories}}{\memglodesc{(\ref {range.factories})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.factories.general@ {\memgloterm{range.factories.general}}{\memglodesc{(\ref {range.factories.general})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.empty@ {\memgloterm{range.empty}}{\memglodesc{(\ref {range.empty})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.empty.overview@ {\memgloterm{range.empty.overview}}{\memglodesc{(\ref {range.empty.overview})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.empty.view@ {\memgloterm{range.empty.view}}{\memglodesc{(\ref {range.empty.view})}} {\memgloref{}}|memjustarg}{1146} -\glossaryentry{range.single@ {\memgloterm{range.single}}{\memglodesc{(\ref {range.single})}} {\memgloref{}}|memjustarg}{1147} -\glossaryentry{range.single.overview@ {\memgloterm{range.single.overview}}{\memglodesc{(\ref {range.single.overview})}} {\memgloref{}}|memjustarg}{1147} -\glossaryentry{range.single.view@ {\memgloterm{range.single.view}}{\memglodesc{(\ref {range.single.view})}} {\memgloref{}}|memjustarg}{1147} -\glossaryentry{range.iota@ {\memgloterm{range.iota}}{\memglodesc{(\ref {range.iota})}} {\memgloref{}}|memjustarg}{1148} -\glossaryentry{range.iota.overview@ {\memgloterm{range.iota.overview}}{\memglodesc{(\ref {range.iota.overview})}} {\memgloref{}}|memjustarg}{1148} -\glossaryentry{range.iota.view@ {\memgloterm{range.iota.view}}{\memglodesc{(\ref {range.iota.view})}} {\memgloref{}}|memjustarg}{1148} -\glossaryentry{range.iota.iterator@ {\memgloterm{range.iota.iterator}}{\memglodesc{(\ref {range.iota.iterator})}} {\memgloref{}}|memjustarg}{1150} -\glossaryentry{range.iota.sentinel@ {\memgloterm{range.iota.sentinel}}{\memglodesc{(\ref {range.iota.sentinel})}} {\memgloref{}}|memjustarg}{1153} -\glossaryentry{range.repeat@ {\memgloterm{range.repeat}}{\memglodesc{(\ref {range.repeat})}} {\memgloref{}}|memjustarg}{1154} -\glossaryentry{range.repeat.overview@ {\memgloterm{range.repeat.overview}}{\memglodesc{(\ref {range.repeat.overview})}} {\memgloref{}}|memjustarg}{1154} -\glossaryentry{range.repeat.view@ {\memgloterm{range.repeat.view}}{\memglodesc{(\ref {range.repeat.view})}} {\memgloref{}}|memjustarg}{1154} -\glossaryentry{range.repeat.iterator@ {\memgloterm{range.repeat.iterator}}{\memglodesc{(\ref {range.repeat.iterator})}} {\memgloref{}}|memjustarg}{1155} -\glossaryentry{range.istream@ {\memgloterm{range.istream}}{\memglodesc{(\ref {range.istream})}} {\memgloref{}}|memjustarg}{1157} -\glossaryentry{range.istream.overview@ {\memgloterm{range.istream.overview}}{\memglodesc{(\ref {range.istream.overview})}} {\memgloref{}}|memjustarg}{1157} -\glossaryentry{range.istream.view@ {\memgloterm{range.istream.view}}{\memglodesc{(\ref {range.istream.view})}} {\memgloref{}}|memjustarg}{1158} -\glossaryentry{range.istream.iterator@ {\memgloterm{range.istream.iterator}}{\memglodesc{(\ref {range.istream.iterator})}} {\memgloref{}}|memjustarg}{1158} -\glossaryentry{range.adaptors@ {\memgloterm{range.adaptors}}{\memglodesc{(\ref {range.adaptors})}} {\memgloref{}}|memjustarg}{1159} -\glossaryentry{range.adaptors.general@ {\memgloterm{range.adaptors.general}}{\memglodesc{(\ref {range.adaptors.general})}} {\memgloref{}}|memjustarg}{1159} -\glossaryentry{range.adaptor.object@ {\memgloterm{range.adaptor.object}}{\memglodesc{(\ref {range.adaptor.object})}} {\memgloref{}}|memjustarg}{1159} -\glossaryentry{range.move.wrap@ {\memgloterm{range.move.wrap}}{\memglodesc{(\ref {range.move.wrap})}} {\memgloref{}}|memjustarg}{1160} -\glossaryentry{range.nonprop.cache@ {\memgloterm{range.nonprop.cache}}{\memglodesc{(\ref {range.nonprop.cache})}} {\memgloref{}}|memjustarg}{1161} -\glossaryentry{range.adaptor.helpers@ {\memgloterm{range.adaptor.helpers}}{\memglodesc{(\ref {range.adaptor.helpers})}} {\memgloref{}}|memjustarg}{1162} -\glossaryentry{range.all@ {\memgloterm{range.all}}{\memglodesc{(\ref {range.all})}} {\memgloref{}}|memjustarg}{1162} -\glossaryentry{range.all.general@ {\memgloterm{range.all.general}}{\memglodesc{(\ref {range.all.general})}} {\memgloref{}}|memjustarg}{1162} -\glossaryentry{range.ref.view@ {\memgloterm{range.ref.view}}{\memglodesc{(\ref {range.ref.view})}} {\memgloref{}}|memjustarg}{1162} -\glossaryentry{range.owning.view@ {\memgloterm{range.owning.view}}{\memglodesc{(\ref {range.owning.view})}} {\memgloref{}}|memjustarg}{1163} -\glossaryentry{range.as.rvalue@ {\memgloterm{range.as.rvalue}}{\memglodesc{(\ref {range.as.rvalue})}} {\memgloref{}}|memjustarg}{1164} -\glossaryentry{range.as.rvalue.overview@ {\memgloterm{range.as.rvalue.overview}}{\memglodesc{(\ref {range.as.rvalue.overview})}} {\memgloref{}}|memjustarg}{1164} -\glossaryentry{range.as.rvalue.view@ {\memgloterm{range.as.rvalue.view}}{\memglodesc{(\ref {range.as.rvalue.view})}} {\memgloref{}}|memjustarg}{1164} -\glossaryentry{range.filter@ {\memgloterm{range.filter}}{\memglodesc{(\ref {range.filter})}} {\memgloref{}}|memjustarg}{1165} -\glossaryentry{range.filter.overview@ {\memgloterm{range.filter.overview}}{\memglodesc{(\ref {range.filter.overview})}} {\memgloref{}}|memjustarg}{1165} -\glossaryentry{range.filter.view@ {\memgloterm{range.filter.view}}{\memglodesc{(\ref {range.filter.view})}} {\memgloref{}}|memjustarg}{1165} -\glossaryentry{range.filter.iterator@ {\memgloterm{range.filter.iterator}}{\memglodesc{(\ref {range.filter.iterator})}} {\memgloref{}}|memjustarg}{1166} -\glossaryentry{range.filter.sentinel@ {\memgloterm{range.filter.sentinel}}{\memglodesc{(\ref {range.filter.sentinel})}} {\memgloref{}}|memjustarg}{1168} -\glossaryentry{range.transform@ {\memgloterm{range.transform}}{\memglodesc{(\ref {range.transform})}} {\memgloref{}}|memjustarg}{1168} -\glossaryentry{range.transform.overview@ {\memgloterm{range.transform.overview}}{\memglodesc{(\ref {range.transform.overview})}} {\memgloref{}}|memjustarg}{1168} -\glossaryentry{range.transform.view@ {\memgloterm{range.transform.view}}{\memglodesc{(\ref {range.transform.view})}} {\memgloref{}}|memjustarg}{1168} -\glossaryentry{range.transform.iterator@ {\memgloterm{range.transform.iterator}}{\memglodesc{(\ref {range.transform.iterator})}} {\memgloref{}}|memjustarg}{1170} -\glossaryentry{range.transform.sentinel@ {\memgloterm{range.transform.sentinel}}{\memglodesc{(\ref {range.transform.sentinel})}} {\memgloref{}}|memjustarg}{1173} -\glossaryentry{range.take@ {\memgloterm{range.take}}{\memglodesc{(\ref {range.take})}} {\memgloref{}}|memjustarg}{1174} -\glossaryentry{range.take.overview@ {\memgloterm{range.take.overview}}{\memglodesc{(\ref {range.take.overview})}} {\memgloref{}}|memjustarg}{1174} -\glossaryentry{range.take.view@ {\memgloterm{range.take.view}}{\memglodesc{(\ref {range.take.view})}} {\memgloref{}}|memjustarg}{1174} -\glossaryentry{range.take.sentinel@ {\memgloterm{range.take.sentinel}}{\memglodesc{(\ref {range.take.sentinel})}} {\memgloref{}}|memjustarg}{1176} -\glossaryentry{range.take.while@ {\memgloterm{range.take.while}}{\memglodesc{(\ref {range.take.while})}} {\memgloref{}}|memjustarg}{1177} -\glossaryentry{range.take.while.overview@ {\memgloterm{range.take.while.overview}}{\memglodesc{(\ref {range.take.while.overview})}} {\memgloref{}}|memjustarg}{1177} -\glossaryentry{range.take.while.view@ {\memgloterm{range.take.while.view}}{\memglodesc{(\ref {range.take.while.view})}} {\memgloref{}}|memjustarg}{1177} -\glossaryentry{range.take.while.sentinel@ {\memgloterm{range.take.while.sentinel}}{\memglodesc{(\ref {range.take.while.sentinel})}} {\memgloref{}}|memjustarg}{1178} -\glossaryentry{range.drop@ {\memgloterm{range.drop}}{\memglodesc{(\ref {range.drop})}} {\memgloref{}}|memjustarg}{1179} -\glossaryentry{range.drop.overview@ {\memgloterm{range.drop.overview}}{\memglodesc{(\ref {range.drop.overview})}} {\memgloref{}}|memjustarg}{1179} -\glossaryentry{range.drop.view@ {\memgloterm{range.drop.view}}{\memglodesc{(\ref {range.drop.view})}} {\memgloref{}}|memjustarg}{1179} -\glossaryentry{range.drop.while@ {\memgloterm{range.drop.while}}{\memglodesc{(\ref {range.drop.while})}} {\memgloref{}}|memjustarg}{1180} -\glossaryentry{range.drop.while.overview@ {\memgloterm{range.drop.while.overview}}{\memglodesc{(\ref {range.drop.while.overview})}} {\memgloref{}}|memjustarg}{1180} -\glossaryentry{range.drop.while.view@ {\memgloterm{range.drop.while.view}}{\memglodesc{(\ref {range.drop.while.view})}} {\memgloref{}}|memjustarg}{1181} -\glossaryentry{range.join@ {\memgloterm{range.join}}{\memglodesc{(\ref {range.join})}} {\memgloref{}}|memjustarg}{1181} -\glossaryentry{range.join.overview@ {\memgloterm{range.join.overview}}{\memglodesc{(\ref {range.join.overview})}} {\memgloref{}}|memjustarg}{1181} -\glossaryentry{range.join.view@ {\memgloterm{range.join.view}}{\memglodesc{(\ref {range.join.view})}} {\memgloref{}}|memjustarg}{1181} -\glossaryentry{range.join.iterator@ {\memgloterm{range.join.iterator}}{\memglodesc{(\ref {range.join.iterator})}} {\memgloref{}}|memjustarg}{1183} -\glossaryentry{range.join.sentinel@ {\memgloterm{range.join.sentinel}}{\memglodesc{(\ref {range.join.sentinel})}} {\memgloref{}}|memjustarg}{1186} -\glossaryentry{range.join.with@ {\memgloterm{range.join.with}}{\memglodesc{(\ref {range.join.with})}} {\memgloref{}}|memjustarg}{1187} -\glossaryentry{range.join.with.overview@ {\memgloterm{range.join.with.overview}}{\memglodesc{(\ref {range.join.with.overview})}} {\memgloref{}}|memjustarg}{1187} -\glossaryentry{range.join.with.view@ {\memgloterm{range.join.with.view}}{\memglodesc{(\ref {range.join.with.view})}} {\memgloref{}}|memjustarg}{1187} -\glossaryentry{range.join.with.iterator@ {\memgloterm{range.join.with.iterator}}{\memglodesc{(\ref {range.join.with.iterator})}} {\memgloref{}}|memjustarg}{1189} -\glossaryentry{range.join.with.sentinel@ {\memgloterm{range.join.with.sentinel}}{\memglodesc{(\ref {range.join.with.sentinel})}} {\memgloref{}}|memjustarg}{1192} -\glossaryentry{range.lazy.split@ {\memgloterm{range.lazy.split}}{\memglodesc{(\ref {range.lazy.split})}} {\memgloref{}}|memjustarg}{1193} -\glossaryentry{range.lazy.split.overview@ {\memgloterm{range.lazy.split.overview}}{\memglodesc{(\ref {range.lazy.split.overview})}} {\memgloref{}}|memjustarg}{1193} -\glossaryentry{range.lazy.split.view@ {\memgloterm{range.lazy.split.view}}{\memglodesc{(\ref {range.lazy.split.view})}} {\memgloref{}}|memjustarg}{1193} -\glossaryentry{range.lazy.split.outer@ {\memgloterm{range.lazy.split.outer}}{\memglodesc{(\ref {range.lazy.split.outer})}} {\memgloref{}}|memjustarg}{1195} -\glossaryentry{range.lazy.split.outer.value@ {\memgloterm{range.lazy.split.outer.value}}{\memglodesc{(\ref {range.lazy.split.outer.value})}} {\memgloref{}}|memjustarg}{1197} -\glossaryentry{range.lazy.split.inner@ {\memgloterm{range.lazy.split.inner}}{\memglodesc{(\ref {range.lazy.split.inner})}} {\memgloref{}}|memjustarg}{1197} -\glossaryentry{range.split@ {\memgloterm{range.split}}{\memglodesc{(\ref {range.split})}} {\memgloref{}}|memjustarg}{1199} -\glossaryentry{range.split.overview@ {\memgloterm{range.split.overview}}{\memglodesc{(\ref {range.split.overview})}} {\memgloref{}}|memjustarg}{1199} -\glossaryentry{range.split.view@ {\memgloterm{range.split.view}}{\memglodesc{(\ref {range.split.view})}} {\memgloref{}}|memjustarg}{1199} -\glossaryentry{range.split.iterator@ {\memgloterm{range.split.iterator}}{\memglodesc{(\ref {range.split.iterator})}} {\memgloref{}}|memjustarg}{1200} -\glossaryentry{range.split.sentinel@ {\memgloterm{range.split.sentinel}}{\memglodesc{(\ref {range.split.sentinel})}} {\memgloref{}}|memjustarg}{1201} -\glossaryentry{range.counted@ {\memgloterm{range.counted}}{\memglodesc{(\ref {range.counted})}} {\memgloref{}}|memjustarg}{1202} -\glossaryentry{range.common@ {\memgloterm{range.common}}{\memglodesc{(\ref {range.common})}} {\memgloref{}}|memjustarg}{1202} -\glossaryentry{range.common.overview@ {\memgloterm{range.common.overview}}{\memglodesc{(\ref {range.common.overview})}} {\memgloref{}}|memjustarg}{1202} -\glossaryentry{range.common.view@ {\memgloterm{range.common.view}}{\memglodesc{(\ref {range.common.view})}} {\memgloref{}}|memjustarg}{1203} -\glossaryentry{range.reverse@ {\memgloterm{range.reverse}}{\memglodesc{(\ref {range.reverse})}} {\memgloref{}}|memjustarg}{1204} -\glossaryentry{range.reverse.overview@ {\memgloterm{range.reverse.overview}}{\memglodesc{(\ref {range.reverse.overview})}} {\memgloref{}}|memjustarg}{1204} -\glossaryentry{range.reverse.view@ {\memgloterm{range.reverse.view}}{\memglodesc{(\ref {range.reverse.view})}} {\memgloref{}}|memjustarg}{1204} -\glossaryentry{range.as.const@ {\memgloterm{range.as.const}}{\memglodesc{(\ref {range.as.const})}} {\memgloref{}}|memjustarg}{1205} -\glossaryentry{range.as.const.overview@ {\memgloterm{range.as.const.overview}}{\memglodesc{(\ref {range.as.const.overview})}} {\memgloref{}}|memjustarg}{1205} -\glossaryentry{range.as.const.view@ {\memgloterm{range.as.const.view}}{\memglodesc{(\ref {range.as.const.view})}} {\memgloref{}}|memjustarg}{1205} -\glossaryentry{range.elements@ {\memgloterm{range.elements}}{\memglodesc{(\ref {range.elements})}} {\memgloref{}}|memjustarg}{1206} -\glossaryentry{range.elements.overview@ {\memgloterm{range.elements.overview}}{\memglodesc{(\ref {range.elements.overview})}} {\memgloref{}}|memjustarg}{1206} -\glossaryentry{range.elements.view@ {\memgloterm{range.elements.view}}{\memglodesc{(\ref {range.elements.view})}} {\memgloref{}}|memjustarg}{1207} -\glossaryentry{range.elements.iterator@ {\memgloterm{range.elements.iterator}}{\memglodesc{(\ref {range.elements.iterator})}} {\memgloref{}}|memjustarg}{1207} -\glossaryentry{range.elements.sentinel@ {\memgloterm{range.elements.sentinel}}{\memglodesc{(\ref {range.elements.sentinel})}} {\memgloref{}}|memjustarg}{1211} -\glossaryentry{range.enumerate@ {\memgloterm{range.enumerate}}{\memglodesc{(\ref {range.enumerate})}} {\memgloref{}}|memjustarg}{1212} -\glossaryentry{range.enumerate.overview@ {\memgloterm{range.enumerate.overview}}{\memglodesc{(\ref {range.enumerate.overview})}} {\memgloref{}}|memjustarg}{1212} -\glossaryentry{range.enumerate.view@ {\memgloterm{range.enumerate.view}}{\memglodesc{(\ref {range.enumerate.view})}} {\memgloref{}}|memjustarg}{1212} -\glossaryentry{range.enumerate.iterator@ {\memgloterm{range.enumerate.iterator}}{\memglodesc{(\ref {range.enumerate.iterator})}} {\memgloref{}}|memjustarg}{1213} -\glossaryentry{range.enumerate.sentinel@ {\memgloterm{range.enumerate.sentinel}}{\memglodesc{(\ref {range.enumerate.sentinel})}} {\memgloref{}}|memjustarg}{1215} -\glossaryentry{range.zip@ {\memgloterm{range.zip}}{\memglodesc{(\ref {range.zip})}} {\memgloref{}}|memjustarg}{1216} -\glossaryentry{range.zip.overview@ {\memgloterm{range.zip.overview}}{\memglodesc{(\ref {range.zip.overview})}} {\memgloref{}}|memjustarg}{1216} -\glossaryentry{range.zip.view@ {\memgloterm{range.zip.view}}{\memglodesc{(\ref {range.zip.view})}} {\memgloref{}}|memjustarg}{1217} -\glossaryentry{range.zip.iterator@ {\memgloterm{range.zip.iterator}}{\memglodesc{(\ref {range.zip.iterator})}} {\memgloref{}}|memjustarg}{1218} -\glossaryentry{range.zip.sentinel@ {\memgloterm{range.zip.sentinel}}{\memglodesc{(\ref {range.zip.sentinel})}} {\memgloref{}}|memjustarg}{1221} -\glossaryentry{range.zip.transform@ {\memgloterm{range.zip.transform}}{\memglodesc{(\ref {range.zip.transform})}} {\memgloref{}}|memjustarg}{1222} -\glossaryentry{range.zip.transform.overview@ {\memgloterm{range.zip.transform.overview}}{\memglodesc{(\ref {range.zip.transform.overview})}} {\memgloref{}}|memjustarg}{1222} -\glossaryentry{range.zip.transform.view@ {\memgloterm{range.zip.transform.view}}{\memglodesc{(\ref {range.zip.transform.view})}} {\memgloref{}}|memjustarg}{1223} -\glossaryentry{range.zip.transform.iterator@ {\memgloterm{range.zip.transform.iterator}}{\memglodesc{(\ref {range.zip.transform.iterator})}} {\memgloref{}}|memjustarg}{1224} -\glossaryentry{range.zip.transform.sentinel@ {\memgloterm{range.zip.transform.sentinel}}{\memglodesc{(\ref {range.zip.transform.sentinel})}} {\memgloref{}}|memjustarg}{1226} -\glossaryentry{range.adjacent@ {\memgloterm{range.adjacent}}{\memglodesc{(\ref {range.adjacent})}} {\memgloref{}}|memjustarg}{1227} -\glossaryentry{range.adjacent.overview@ {\memgloterm{range.adjacent.overview}}{\memglodesc{(\ref {range.adjacent.overview})}} {\memgloref{}}|memjustarg}{1227} -\glossaryentry{range.adjacent.view@ {\memgloterm{range.adjacent.view}}{\memglodesc{(\ref {range.adjacent.view})}} {\memgloref{}}|memjustarg}{1228} -\glossaryentry{range.adjacent.iterator@ {\memgloterm{range.adjacent.iterator}}{\memglodesc{(\ref {range.adjacent.iterator})}} {\memgloref{}}|memjustarg}{1229} -\glossaryentry{range.adjacent.sentinel@ {\memgloterm{range.adjacent.sentinel}}{\memglodesc{(\ref {range.adjacent.sentinel})}} {\memgloref{}}|memjustarg}{1232} -\glossaryentry{range.adjacent.transform@ {\memgloterm{range.adjacent.transform}}{\memglodesc{(\ref {range.adjacent.transform})}} {\memgloref{}}|memjustarg}{1233} -\glossaryentry{range.adjacent.transform.overview@ {\memgloterm{range.adjacent.transform.overview}}{\memglodesc{(\ref {range.adjacent.transform.overview})}} {\memgloref{}}|memjustarg}{1233} -\glossaryentry{range.adjacent.transform.view@ {\memgloterm{range.adjacent.transform.view}}{\memglodesc{(\ref {range.adjacent.transform.view})}} {\memgloref{}}|memjustarg}{1233} -\glossaryentry{range.adjacent.transform.iterator@ {\memgloterm{range.adjacent.transform.iterator}}{\memglodesc{(\ref {range.adjacent.transform.iterator})}} {\memgloref{}}|memjustarg}{1234} -\glossaryentry{range.adjacent.transform.sentinel@ {\memgloterm{range.adjacent.transform.sentinel}}{\memglodesc{(\ref {range.adjacent.transform.sentinel})}} {\memgloref{}}|memjustarg}{1237} -\glossaryentry{range.chunk@ {\memgloterm{range.chunk}}{\memglodesc{(\ref {range.chunk})}} {\memgloref{}}|memjustarg}{1238} -\glossaryentry{range.chunk.overview@ {\memgloterm{range.chunk.overview}}{\memglodesc{(\ref {range.chunk.overview})}} {\memgloref{}}|memjustarg}{1238} -\glossaryentry{range.chunk.view.input@ {\memgloterm{range.chunk.view.input}}{\memglodesc{(\ref {range.chunk.view.input})}} {\memgloref{}}|memjustarg}{1238} -\glossaryentry{range.chunk.outer.iter@ {\memgloterm{range.chunk.outer.iter}}{\memglodesc{(\ref {range.chunk.outer.iter})}} {\memgloref{}}|memjustarg}{1239} -\glossaryentry{range.chunk.outer.value@ {\memgloterm{range.chunk.outer.value}}{\memglodesc{(\ref {range.chunk.outer.value})}} {\memgloref{}}|memjustarg}{1240} -\glossaryentry{range.chunk.inner.iter@ {\memgloterm{range.chunk.inner.iter}}{\memglodesc{(\ref {range.chunk.inner.iter})}} {\memgloref{}}|memjustarg}{1241} -\glossaryentry{range.chunk.view.fwd@ {\memgloterm{range.chunk.view.fwd}}{\memglodesc{(\ref {range.chunk.view.fwd})}} {\memgloref{}}|memjustarg}{1242} -\glossaryentry{range.chunk.fwd.iter@ {\memgloterm{range.chunk.fwd.iter}}{\memglodesc{(\ref {range.chunk.fwd.iter})}} {\memgloref{}}|memjustarg}{1243} -\glossaryentry{range.slide@ {\memgloterm{range.slide}}{\memglodesc{(\ref {range.slide})}} {\memgloref{}}|memjustarg}{1247} -\glossaryentry{range.slide.overview@ {\memgloterm{range.slide.overview}}{\memglodesc{(\ref {range.slide.overview})}} {\memgloref{}}|memjustarg}{1247} -\glossaryentry{range.slide.view@ {\memgloterm{range.slide.view}}{\memglodesc{(\ref {range.slide.view})}} {\memgloref{}}|memjustarg}{1247} -\glossaryentry{range.slide.iterator@ {\memgloterm{range.slide.iterator}}{\memglodesc{(\ref {range.slide.iterator})}} {\memgloref{}}|memjustarg}{1248} -\glossaryentry{range.slide.sentinel@ {\memgloterm{range.slide.sentinel}}{\memglodesc{(\ref {range.slide.sentinel})}} {\memgloref{}}|memjustarg}{1252} -\glossaryentry{range.chunk.by@ {\memgloterm{range.chunk.by}}{\memglodesc{(\ref {range.chunk.by})}} {\memgloref{}}|memjustarg}{1252} -\glossaryentry{range.chunk.by.overview@ {\memgloterm{range.chunk.by.overview}}{\memglodesc{(\ref {range.chunk.by.overview})}} {\memgloref{}}|memjustarg}{1252} -\glossaryentry{range.chunk.by.view@ {\memgloterm{range.chunk.by.view}}{\memglodesc{(\ref {range.chunk.by.view})}} {\memgloref{}}|memjustarg}{1253} -\glossaryentry{range.chunk.by.iter@ {\memgloterm{range.chunk.by.iter}}{\memglodesc{(\ref {range.chunk.by.iter})}} {\memgloref{}}|memjustarg}{1254} -\glossaryentry{range.stride@ {\memgloterm{range.stride}}{\memglodesc{(\ref {range.stride})}} {\memgloref{}}|memjustarg}{1255} -\glossaryentry{range.stride.overview@ {\memgloterm{range.stride.overview}}{\memglodesc{(\ref {range.stride.overview})}} {\memgloref{}}|memjustarg}{1255} -\glossaryentry{range.stride.view@ {\memgloterm{range.stride.view}}{\memglodesc{(\ref {range.stride.view})}} {\memgloref{}}|memjustarg}{1255} -\glossaryentry{range.stride.iterator@ {\memgloterm{range.stride.iterator}}{\memglodesc{(\ref {range.stride.iterator})}} {\memgloref{}}|memjustarg}{1256} -\glossaryentry{range.cartesian@ {\memgloterm{range.cartesian}}{\memglodesc{(\ref {range.cartesian})}} {\memgloref{}}|memjustarg}{1260} -\glossaryentry{range.cartesian.overview@ {\memgloterm{range.cartesian.overview}}{\memglodesc{(\ref {range.cartesian.overview})}} {\memgloref{}}|memjustarg}{1260} -\glossaryentry{range.cartesian.view@ {\memgloterm{range.cartesian.view}}{\memglodesc{(\ref {range.cartesian.view})}} {\memgloref{}}|memjustarg}{1261} -\glossaryentry{range.cartesian.iterator@ {\memgloterm{range.cartesian.iterator}}{\memglodesc{(\ref {range.cartesian.iterator})}} {\memgloref{}}|memjustarg}{1263} -\glossaryentry{coro.generator@ {\memgloterm{coro.generator}}{\memglodesc{(\ref {coro.generator})}} {\memgloref{}}|memjustarg}{1267} -\glossaryentry{coroutine.generator.overview@ {\memgloterm{coroutine.generator.overview}}{\memglodesc{(\ref {coroutine.generator.overview})}} {\memgloref{}}|memjustarg}{1267} -\glossaryentry{generator.syn@ {\memgloterm{generator.syn}}{\memglodesc{(\ref {generator.syn})}} {\memgloref{}}|memjustarg}{1268} -\glossaryentry{coro.generator.class@ {\memgloterm{coro.generator.class}}{\memglodesc{(\ref {coro.generator.class})}} {\memgloref{}}|memjustarg}{1268} -\glossaryentry{coro.generator.members@ {\memgloterm{coro.generator.members}}{\memglodesc{(\ref {coro.generator.members})}} {\memgloref{}}|memjustarg}{1269} -\glossaryentry{coro.generator.promise@ {\memgloterm{coro.generator.promise}}{\memglodesc{(\ref {coro.generator.promise})}} {\memgloref{}}|memjustarg}{1269} -\glossaryentry{coro.generator.iterator@ {\memgloterm{coro.generator.iterator}}{\memglodesc{(\ref {coro.generator.iterator})}} {\memgloref{}}|memjustarg}{1272} -\glossaryentry{algorithms@ {\memgloterm{algorithms}}{\memglodesc{(\ref {algorithms})}} {\memgloref{}}|memjustarg}{1273} -\glossaryentry{algorithms.general@ {\memgloterm{algorithms.general}}{\memglodesc{(\ref {algorithms.general})}} {\memgloref{}}|memjustarg}{1273} -\glossaryentry{algorithms.requirements@ {\memgloterm{algorithms.requirements}}{\memglodesc{(\ref {algorithms.requirements})}} {\memgloref{}}|memjustarg}{1273} -\glossaryentry{algorithms.parallel@ {\memgloterm{algorithms.parallel}}{\memglodesc{(\ref {algorithms.parallel})}} {\memgloref{}}|memjustarg}{1275} -\glossaryentry{algorithms.parallel.defns@ {\memgloterm{algorithms.parallel.defns}}{\memglodesc{(\ref {algorithms.parallel.defns})}} {\memgloref{}}|memjustarg}{1275} -\glossaryentry{algorithms.parallel.user@ {\memgloterm{algorithms.parallel.user}}{\memglodesc{(\ref {algorithms.parallel.user})}} {\memgloref{}}|memjustarg}{1276} -\glossaryentry{algorithms.parallel.exec@ {\memgloterm{algorithms.parallel.exec}}{\memglodesc{(\ref {algorithms.parallel.exec})}} {\memgloref{}}|memjustarg}{1276} -\glossaryentry{algorithms.parallel.exceptions@ {\memgloterm{algorithms.parallel.exceptions}}{\memglodesc{(\ref {algorithms.parallel.exceptions})}} {\memgloref{}}|memjustarg}{1278} -\glossaryentry{algorithms.parallel.overloads@ {\memgloterm{algorithms.parallel.overloads}}{\memglodesc{(\ref {algorithms.parallel.overloads})}} {\memgloref{}}|memjustarg}{1278} -\glossaryentry{algorithm.syn@ {\memgloterm{algorithm.syn}}{\memglodesc{(\ref {algorithm.syn})}} {\memgloref{}}|memjustarg}{1278} -\glossaryentry{algorithms.results@ {\memgloterm{algorithms.results}}{\memglodesc{(\ref {algorithms.results})}} {\memgloref{}}|memjustarg}{1316} -\glossaryentry{alg.nonmodifying@ {\memgloterm{alg.nonmodifying}}{\memglodesc{(\ref {alg.nonmodifying})}} {\memgloref{}}|memjustarg}{1319} -\glossaryentry{alg.all.of@ {\memgloterm{alg.all.of}}{\memglodesc{(\ref {alg.all.of})}} {\memgloref{}}|memjustarg}{1319} -\glossaryentry{alg.any.of@ {\memgloterm{alg.any.of}}{\memglodesc{(\ref {alg.any.of})}} {\memgloref{}}|memjustarg}{1320} -\glossaryentry{alg.none.of@ {\memgloterm{alg.none.of}}{\memglodesc{(\ref {alg.none.of})}} {\memgloref{}}|memjustarg}{1320} -\glossaryentry{alg.contains@ {\memgloterm{alg.contains}}{\memglodesc{(\ref {alg.contains})}} {\memgloref{}}|memjustarg}{1320} -\glossaryentry{alg.foreach@ {\memgloterm{alg.foreach}}{\memglodesc{(\ref {alg.foreach})}} {\memgloref{}}|memjustarg}{1321} -\glossaryentry{alg.find@ {\memgloterm{alg.find}}{\memglodesc{(\ref {alg.find})}} {\memgloref{}}|memjustarg}{1322} -\glossaryentry{alg.find.last@ {\memgloterm{alg.find.last}}{\memglodesc{(\ref {alg.find.last})}} {\memgloref{}}|memjustarg}{1323} -\glossaryentry{alg.find.end@ {\memgloterm{alg.find.end}}{\memglodesc{(\ref {alg.find.end})}} {\memgloref{}}|memjustarg}{1324} -\glossaryentry{alg.find.first.of@ {\memgloterm{alg.find.first.of}}{\memglodesc{(\ref {alg.find.first.of})}} {\memgloref{}}|memjustarg}{1324} -\glossaryentry{alg.adjacent.find@ {\memgloterm{alg.adjacent.find}}{\memglodesc{(\ref {alg.adjacent.find})}} {\memgloref{}}|memjustarg}{1325} -\glossaryentry{alg.count@ {\memgloterm{alg.count}}{\memglodesc{(\ref {alg.count})}} {\memgloref{}}|memjustarg}{1326} -\glossaryentry{mismatch@ {\memgloterm{mismatch}}{\memglodesc{(\ref {mismatch})}} {\memgloref{}}|memjustarg}{1327} -\glossaryentry{alg.equal@ {\memgloterm{alg.equal}}{\memglodesc{(\ref {alg.equal})}} {\memgloref{}}|memjustarg}{1328} -\glossaryentry{alg.is.permutation@ {\memgloterm{alg.is.permutation}}{\memglodesc{(\ref {alg.is.permutation})}} {\memgloref{}}|memjustarg}{1329} -\glossaryentry{alg.search@ {\memgloterm{alg.search}}{\memglodesc{(\ref {alg.search})}} {\memgloref{}}|memjustarg}{1330} -\glossaryentry{alg.starts.with@ {\memgloterm{alg.starts.with}}{\memglodesc{(\ref {alg.starts.with})}} {\memgloref{}}|memjustarg}{1332} -\glossaryentry{alg.ends.with@ {\memgloterm{alg.ends.with}}{\memglodesc{(\ref {alg.ends.with})}} {\memgloref{}}|memjustarg}{1332} -\glossaryentry{alg.fold@ {\memgloterm{alg.fold}}{\memglodesc{(\ref {alg.fold})}} {\memgloref{}}|memjustarg}{1333} -\glossaryentry{alg.modifying.operations@ {\memgloterm{alg.modifying.operations}}{\memglodesc{(\ref {alg.modifying.operations})}} {\memgloref{}}|memjustarg}{1334} -\glossaryentry{alg.copy@ {\memgloterm{alg.copy}}{\memglodesc{(\ref {alg.copy})}} {\memgloref{}}|memjustarg}{1334} -\glossaryentry{alg.move@ {\memgloterm{alg.move}}{\memglodesc{(\ref {alg.move})}} {\memgloref{}}|memjustarg}{1336} -\glossaryentry{alg.swap@ {\memgloterm{alg.swap}}{\memglodesc{(\ref {alg.swap})}} {\memgloref{}}|memjustarg}{1338} -\glossaryentry{alg.transform@ {\memgloterm{alg.transform}}{\memglodesc{(\ref {alg.transform})}} {\memgloref{}}|memjustarg}{1338} -\glossaryentry{alg.replace@ {\memgloterm{alg.replace}}{\memglodesc{(\ref {alg.replace})}} {\memgloref{}}|memjustarg}{1340} -\glossaryentry{alg.fill@ {\memgloterm{alg.fill}}{\memglodesc{(\ref {alg.fill})}} {\memgloref{}}|memjustarg}{1342} -\glossaryentry{alg.generate@ {\memgloterm{alg.generate}}{\memglodesc{(\ref {alg.generate})}} {\memgloref{}}|memjustarg}{1342} -\glossaryentry{alg.remove@ {\memgloterm{alg.remove}}{\memglodesc{(\ref {alg.remove})}} {\memgloref{}}|memjustarg}{1343} -\glossaryentry{alg.unique@ {\memgloterm{alg.unique}}{\memglodesc{(\ref {alg.unique})}} {\memgloref{}}|memjustarg}{1345} -\glossaryentry{alg.reverse@ {\memgloterm{alg.reverse}}{\memglodesc{(\ref {alg.reverse})}} {\memgloref{}}|memjustarg}{1347} -\glossaryentry{alg.rotate@ {\memgloterm{alg.rotate}}{\memglodesc{(\ref {alg.rotate})}} {\memgloref{}}|memjustarg}{1347} -\glossaryentry{alg.random.sample@ {\memgloterm{alg.random.sample}}{\memglodesc{(\ref {alg.random.sample})}} {\memgloref{}}|memjustarg}{1349} -\glossaryentry{alg.random.shuffle@ {\memgloterm{alg.random.shuffle}}{\memglodesc{(\ref {alg.random.shuffle})}} {\memgloref{}}|memjustarg}{1349} -\glossaryentry{alg.shift@ {\memgloterm{alg.shift}}{\memglodesc{(\ref {alg.shift})}} {\memgloref{}}|memjustarg}{1350} -\glossaryentry{alg.sorting@ {\memgloterm{alg.sorting}}{\memglodesc{(\ref {alg.sorting})}} {\memgloref{}}|memjustarg}{1351} -\glossaryentry{alg.sorting.general@ {\memgloterm{alg.sorting.general}}{\memglodesc{(\ref {alg.sorting.general})}} {\memgloref{}}|memjustarg}{1351} -\glossaryentry{alg.sort@ {\memgloterm{alg.sort}}{\memglodesc{(\ref {alg.sort})}} {\memgloref{}}|memjustarg}{1351} -\glossaryentry{sort@ {\memgloterm{sort}}{\memglodesc{(\ref {sort})}} {\memgloref{}}|memjustarg}{1351} -\glossaryentry{stable.sort@ {\memgloterm{stable.sort}}{\memglodesc{(\ref {stable.sort})}} {\memgloref{}}|memjustarg}{1352} -\glossaryentry{partial.sort@ {\memgloterm{partial.sort}}{\memglodesc{(\ref {partial.sort})}} {\memgloref{}}|memjustarg}{1353} -\glossaryentry{partial.sort.copy@ {\memgloterm{partial.sort.copy}}{\memglodesc{(\ref {partial.sort.copy})}} {\memgloref{}}|memjustarg}{1353} -\glossaryentry{is.sorted@ {\memgloterm{is.sorted}}{\memglodesc{(\ref {is.sorted})}} {\memgloref{}}|memjustarg}{1355} -\glossaryentry{alg.nth.element@ {\memgloterm{alg.nth.element}}{\memglodesc{(\ref {alg.nth.element})}} {\memgloref{}}|memjustarg}{1356} -\glossaryentry{alg.binary.search@ {\memgloterm{alg.binary.search}}{\memglodesc{(\ref {alg.binary.search})}} {\memgloref{}}|memjustarg}{1356} -\glossaryentry{alg.binary.search.general@ {\memgloterm{alg.binary.search.general}}{\memglodesc{(\ref {alg.binary.search.general})}} {\memgloref{}}|memjustarg}{1356} -\glossaryentry{lower.bound@ {\memgloterm{lower.bound}}{\memglodesc{(\ref {lower.bound})}} {\memgloref{}}|memjustarg}{1356} -\glossaryentry{upper.bound@ {\memgloterm{upper.bound}}{\memglodesc{(\ref {upper.bound})}} {\memgloref{}}|memjustarg}{1357} -\glossaryentry{equal.range@ {\memgloterm{equal.range}}{\memglodesc{(\ref {equal.range})}} {\memgloref{}}|memjustarg}{1357} -\glossaryentry{binary.search@ {\memgloterm{binary.search}}{\memglodesc{(\ref {binary.search})}} {\memgloref{}}|memjustarg}{1358} -\glossaryentry{alg.partitions@ {\memgloterm{alg.partitions}}{\memglodesc{(\ref {alg.partitions})}} {\memgloref{}}|memjustarg}{1359} -\glossaryentry{alg.merge@ {\memgloterm{alg.merge}}{\memglodesc{(\ref {alg.merge})}} {\memgloref{}}|memjustarg}{1361} -\glossaryentry{alg.set.operations@ {\memgloterm{alg.set.operations}}{\memglodesc{(\ref {alg.set.operations})}} {\memgloref{}}|memjustarg}{1363} -\glossaryentry{alg.set.operations.general@ {\memgloterm{alg.set.operations.general}}{\memglodesc{(\ref {alg.set.operations.general})}} {\memgloref{}}|memjustarg}{1363} -\glossaryentry{includes@ {\memgloterm{includes}}{\memglodesc{(\ref {includes})}} {\memgloref{}}|memjustarg}{1363} -\glossaryentry{set.union@ {\memgloterm{set.union}}{\memglodesc{(\ref {set.union})}} {\memgloref{}}|memjustarg}{1364} -\glossaryentry{set.intersection@ {\memgloterm{set.intersection}}{\memglodesc{(\ref {set.intersection})}} {\memgloref{}}|memjustarg}{1365} -\glossaryentry{set.difference@ {\memgloterm{set.difference}}{\memglodesc{(\ref {set.difference})}} {\memgloref{}}|memjustarg}{1366} -\glossaryentry{set.symmetric.difference@ {\memgloterm{set.symmetric.difference}}{\memglodesc{(\ref {set.symmetric.difference})}} {\memgloref{}}|memjustarg}{1367} -\glossaryentry{alg.heap.operations@ {\memgloterm{alg.heap.operations}}{\memglodesc{(\ref {alg.heap.operations})}} {\memgloref{}}|memjustarg}{1368} -\glossaryentry{alg.heap.operations.general@ {\memgloterm{alg.heap.operations.general}}{\memglodesc{(\ref {alg.heap.operations.general})}} {\memgloref{}}|memjustarg}{1368} -\glossaryentry{push.heap@ {\memgloterm{push.heap}}{\memglodesc{(\ref {push.heap})}} {\memgloref{}}|memjustarg}{1368} -\glossaryentry{pop.heap@ {\memgloterm{pop.heap}}{\memglodesc{(\ref {pop.heap})}} {\memgloref{}}|memjustarg}{1368} -\glossaryentry{make.heap@ {\memgloterm{make.heap}}{\memglodesc{(\ref {make.heap})}} {\memgloref{}}|memjustarg}{1369} -\glossaryentry{sort.heap@ {\memgloterm{sort.heap}}{\memglodesc{(\ref {sort.heap})}} {\memgloref{}}|memjustarg}{1369} -\glossaryentry{is.heap@ {\memgloterm{is.heap}}{\memglodesc{(\ref {is.heap})}} {\memgloref{}}|memjustarg}{1370} -\glossaryentry{alg.min.max@ {\memgloterm{alg.min.max}}{\memglodesc{(\ref {alg.min.max})}} {\memgloref{}}|memjustarg}{1371} -\glossaryentry{alg.clamp@ {\memgloterm{alg.clamp}}{\memglodesc{(\ref {alg.clamp})}} {\memgloref{}}|memjustarg}{1374} -\glossaryentry{alg.lex.comparison@ {\memgloterm{alg.lex.comparison}}{\memglodesc{(\ref {alg.lex.comparison})}} {\memgloref{}}|memjustarg}{1375} -\glossaryentry{alg.three.way@ {\memgloterm{alg.three.way}}{\memglodesc{(\ref {alg.three.way})}} {\memgloref{}}|memjustarg}{1376} -\glossaryentry{alg.permutation.generators@ {\memgloterm{alg.permutation.generators}}{\memglodesc{(\ref {alg.permutation.generators})}} {\memgloref{}}|memjustarg}{1376} -\glossaryentry{numeric.ops.overview@ {\memgloterm{numeric.ops.overview}}{\memglodesc{(\ref {numeric.ops.overview})}} {\memgloref{}}|memjustarg}{1377} -\glossaryentry{numeric.ops@ {\memgloterm{numeric.ops}}{\memglodesc{(\ref {numeric.ops})}} {\memgloref{}}|memjustarg}{1381} -\glossaryentry{numeric.ops.general@ {\memgloterm{numeric.ops.general}}{\memglodesc{(\ref {numeric.ops.general})}} {\memgloref{}}|memjustarg}{1381} -\glossaryentry{numerics.defns@ {\memgloterm{numerics.defns}}{\memglodesc{(\ref {numerics.defns})}} {\memgloref{}}|memjustarg}{1381} -\glossaryentry{accumulate@ {\memgloterm{accumulate}}{\memglodesc{(\ref {accumulate})}} {\memgloref{}}|memjustarg}{1381} -\glossaryentry{reduce@ {\memgloterm{reduce}}{\memglodesc{(\ref {reduce})}} {\memgloref{}}|memjustarg}{1381} -\glossaryentry{inner.product@ {\memgloterm{inner.product}}{\memglodesc{(\ref {inner.product})}} {\memgloref{}}|memjustarg}{1382} -\glossaryentry{transform.reduce@ {\memgloterm{transform.reduce}}{\memglodesc{(\ref {transform.reduce})}} {\memgloref{}}|memjustarg}{1382} -\glossaryentry{partial.sum@ {\memgloterm{partial.sum}}{\memglodesc{(\ref {partial.sum})}} {\memgloref{}}|memjustarg}{1384} -\glossaryentry{exclusive.scan@ {\memgloterm{exclusive.scan}}{\memglodesc{(\ref {exclusive.scan})}} {\memgloref{}}|memjustarg}{1384} -\glossaryentry{inclusive.scan@ {\memgloterm{inclusive.scan}}{\memglodesc{(\ref {inclusive.scan})}} {\memgloref{}}|memjustarg}{1385} -\glossaryentry{transform.exclusive.scan@ {\memgloterm{transform.exclusive.scan}}{\memglodesc{(\ref {transform.exclusive.scan})}} {\memgloref{}}|memjustarg}{1386} -\glossaryentry{transform.inclusive.scan@ {\memgloterm{transform.inclusive.scan}}{\memglodesc{(\ref {transform.inclusive.scan})}} {\memgloref{}}|memjustarg}{1387} -\glossaryentry{adjacent.difference@ {\memgloterm{adjacent.difference}}{\memglodesc{(\ref {adjacent.difference})}} {\memgloref{}}|memjustarg}{1388} -\glossaryentry{numeric.iota@ {\memgloterm{numeric.iota}}{\memglodesc{(\ref {numeric.iota})}} {\memgloref{}}|memjustarg}{1389} -\glossaryentry{numeric.ops.gcd@ {\memgloterm{numeric.ops.gcd}}{\memglodesc{(\ref {numeric.ops.gcd})}} {\memgloref{}}|memjustarg}{1389} -\glossaryentry{numeric.ops.lcm@ {\memgloterm{numeric.ops.lcm}}{\memglodesc{(\ref {numeric.ops.lcm})}} {\memgloref{}}|memjustarg}{1390} -\glossaryentry{numeric.ops.midpoint@ {\memgloterm{numeric.ops.midpoint}}{\memglodesc{(\ref {numeric.ops.midpoint})}} {\memgloref{}}|memjustarg}{1390} -\glossaryentry{specialized.algorithms@ {\memgloterm{specialized.algorithms}}{\memglodesc{(\ref {specialized.algorithms})}} {\memgloref{}}|memjustarg}{1390} -\glossaryentry{specialized.algorithms.general@ {\memgloterm{specialized.algorithms.general}}{\memglodesc{(\ref {specialized.algorithms.general})}} {\memgloref{}}|memjustarg}{1390} -\glossaryentry{special.mem.concepts@ {\memgloterm{special.mem.concepts}}{\memglodesc{(\ref {special.mem.concepts})}} {\memgloref{}}|memjustarg}{1390} -\glossaryentry{uninitialized.construct.default@ {\memgloterm{uninitialized.construct.default}}{\memglodesc{(\ref {uninitialized.construct.default})}} {\memgloref{}}|memjustarg}{1391} -\glossaryentry{uninitialized.construct.value@ {\memgloterm{uninitialized.construct.value}}{\memglodesc{(\ref {uninitialized.construct.value})}} {\memgloref{}}|memjustarg}{1392} -\glossaryentry{uninitialized.copy@ {\memgloterm{uninitialized.copy}}{\memglodesc{(\ref {uninitialized.copy})}} {\memgloref{}}|memjustarg}{1392} -\glossaryentry{uninitialized.move@ {\memgloterm{uninitialized.move}}{\memglodesc{(\ref {uninitialized.move})}} {\memgloref{}}|memjustarg}{1393} -\glossaryentry{uninitialized.fill@ {\memgloterm{uninitialized.fill}}{\memglodesc{(\ref {uninitialized.fill})}} {\memgloref{}}|memjustarg}{1394} -\glossaryentry{specialized.construct@ {\memgloterm{specialized.construct}}{\memglodesc{(\ref {specialized.construct})}} {\memgloref{}}|memjustarg}{1395} -\glossaryentry{specialized.destroy@ {\memgloterm{specialized.destroy}}{\memglodesc{(\ref {specialized.destroy})}} {\memgloref{}}|memjustarg}{1395} -\glossaryentry{alg.c.library@ {\memgloterm{alg.c.library}}{\memglodesc{(\ref {alg.c.library})}} {\memgloref{}}|memjustarg}{1396} -\glossaryentry{numerics@ {\memgloterm{numerics}}{\memglodesc{(\ref {numerics})}} {\memgloref{}}|memjustarg}{1397} -\glossaryentry{numerics.general@ {\memgloterm{numerics.general}}{\memglodesc{(\ref {numerics.general})}} {\memgloref{}}|memjustarg}{1397} -\glossaryentry{numeric.requirements@ {\memgloterm{numeric.requirements}}{\memglodesc{(\ref {numeric.requirements})}} {\memgloref{}}|memjustarg}{1397} -\glossaryentry{cfenv@ {\memgloterm{cfenv}}{\memglodesc{(\ref {cfenv})}} {\memgloref{}}|memjustarg}{1397} -\glossaryentry{cfenv.syn@ {\memgloterm{cfenv.syn}}{\memglodesc{(\ref {cfenv.syn})}} {\memgloref{}}|memjustarg}{1397} -\glossaryentry{cfenv.thread@ {\memgloterm{cfenv.thread}}{\memglodesc{(\ref {cfenv.thread})}} {\memgloref{}}|memjustarg}{1398} -\glossaryentry{complex.numbers@ {\memgloterm{complex.numbers}}{\memglodesc{(\ref {complex.numbers})}} {\memgloref{}}|memjustarg}{1398} -\glossaryentry{complex.numbers.general@ {\memgloterm{complex.numbers.general}}{\memglodesc{(\ref {complex.numbers.general})}} {\memgloref{}}|memjustarg}{1398} -\glossaryentry{complex.syn@ {\memgloterm{complex.syn}}{\memglodesc{(\ref {complex.syn})}} {\memgloref{}}|memjustarg}{1398} -\glossaryentry{complex@ {\memgloterm{complex}}{\memglodesc{(\ref {complex})}} {\memgloref{}}|memjustarg}{1400} -\glossaryentry{complex.members@ {\memgloterm{complex.members}}{\memglodesc{(\ref {complex.members})}} {\memgloref{}}|memjustarg}{1400} -\glossaryentry{complex.member.ops@ {\memgloterm{complex.member.ops}}{\memglodesc{(\ref {complex.member.ops})}} {\memgloref{}}|memjustarg}{1401} -\glossaryentry{complex.ops@ {\memgloterm{complex.ops}}{\memglodesc{(\ref {complex.ops})}} {\memgloref{}}|memjustarg}{1401} -\glossaryentry{complex.value.ops@ {\memgloterm{complex.value.ops}}{\memglodesc{(\ref {complex.value.ops})}} {\memgloref{}}|memjustarg}{1402} -\glossaryentry{complex.transcendentals@ {\memgloterm{complex.transcendentals}}{\memglodesc{(\ref {complex.transcendentals})}} {\memgloref{}}|memjustarg}{1403} -\glossaryentry{cmplx.over@ {\memgloterm{cmplx.over}}{\memglodesc{(\ref {cmplx.over})}} {\memgloref{}}|memjustarg}{1404} -\glossaryentry{complex.literals@ {\memgloterm{complex.literals}}{\memglodesc{(\ref {complex.literals})}} {\memgloref{}}|memjustarg}{1404} -\glossaryentry{rand@ {\memgloterm{rand}}{\memglodesc{(\ref {rand})}} {\memgloref{}}|memjustarg}{1405} -\glossaryentry{rand.general@ {\memgloterm{rand.general}}{\memglodesc{(\ref {rand.general})}} {\memgloref{}}|memjustarg}{1405} -\glossaryentry{rand.synopsis@ {\memgloterm{rand.synopsis}}{\memglodesc{(\ref {rand.synopsis})}} {\memgloref{}}|memjustarg}{1405} -\glossaryentry{rand.req@ {\memgloterm{rand.req}}{\memglodesc{(\ref {rand.req})}} {\memgloref{}}|memjustarg}{1407} -\glossaryentry{rand.req.genl@ {\memgloterm{rand.req.genl}}{\memglodesc{(\ref {rand.req.genl})}} {\memgloref{}}|memjustarg}{1407} -\glossaryentry{rand.req.seedseq@ {\memgloterm{rand.req.seedseq}}{\memglodesc{(\ref {rand.req.seedseq})}} {\memgloref{}}|memjustarg}{1408} -\glossaryentry{rand.req.urng@ {\memgloterm{rand.req.urng}}{\memglodesc{(\ref {rand.req.urng})}} {\memgloref{}}|memjustarg}{1409} -\glossaryentry{rand.req.eng@ {\memgloterm{rand.req.eng}}{\memglodesc{(\ref {rand.req.eng})}} {\memgloref{}}|memjustarg}{1409} -\glossaryentry{rand.req.adapt@ {\memgloterm{rand.req.adapt}}{\memglodesc{(\ref {rand.req.adapt})}} {\memgloref{}}|memjustarg}{1411} -\glossaryentry{rand.req.dist@ {\memgloterm{rand.req.dist}}{\memglodesc{(\ref {rand.req.dist})}} {\memgloref{}}|memjustarg}{1412} -\glossaryentry{rand.eng@ {\memgloterm{rand.eng}}{\memglodesc{(\ref {rand.eng})}} {\memgloref{}}|memjustarg}{1414} -\glossaryentry{rand.eng.general@ {\memgloterm{rand.eng.general}}{\memglodesc{(\ref {rand.eng.general})}} {\memgloref{}}|memjustarg}{1414} -\glossaryentry{rand.eng.lcong@ {\memgloterm{rand.eng.lcong}}{\memglodesc{(\ref {rand.eng.lcong})}} {\memgloref{}}|memjustarg}{1415} -\glossaryentry{rand.eng.mers@ {\memgloterm{rand.eng.mers}}{\memglodesc{(\ref {rand.eng.mers})}} {\memgloref{}}|memjustarg}{1416} -\glossaryentry{rand.eng.sub@ {\memgloterm{rand.eng.sub}}{\memglodesc{(\ref {rand.eng.sub})}} {\memgloref{}}|memjustarg}{1417} -\glossaryentry{rand.adapt@ {\memgloterm{rand.adapt}}{\memglodesc{(\ref {rand.adapt})}} {\memgloref{}}|memjustarg}{1419} -\glossaryentry{rand.adapt.general@ {\memgloterm{rand.adapt.general}}{\memglodesc{(\ref {rand.adapt.general})}} {\memgloref{}}|memjustarg}{1419} -\glossaryentry{rand.adapt.disc@ {\memgloterm{rand.adapt.disc}}{\memglodesc{(\ref {rand.adapt.disc})}} {\memgloref{}}|memjustarg}{1419} -\glossaryentry{rand.adapt.ibits@ {\memgloterm{rand.adapt.ibits}}{\memglodesc{(\ref {rand.adapt.ibits})}} {\memgloref{}}|memjustarg}{1420} -\glossaryentry{rand.adapt.shuf@ {\memgloterm{rand.adapt.shuf}}{\memglodesc{(\ref {rand.adapt.shuf})}} {\memgloref{}}|memjustarg}{1421} -\glossaryentry{rand.predef@ {\memgloterm{rand.predef}}{\memglodesc{(\ref {rand.predef})}} {\memgloref{}}|memjustarg}{1422} -\glossaryentry{rand.device@ {\memgloterm{rand.device}}{\memglodesc{(\ref {rand.device})}} {\memgloref{}}|memjustarg}{1423} -\glossaryentry{rand.util@ {\memgloterm{rand.util}}{\memglodesc{(\ref {rand.util})}} {\memgloref{}}|memjustarg}{1424} -\glossaryentry{rand.util.seedseq@ {\memgloterm{rand.util.seedseq}}{\memglodesc{(\ref {rand.util.seedseq})}} {\memgloref{}}|memjustarg}{1424} -\glossaryentry{rand.util.canonical@ {\memgloterm{rand.util.canonical}}{\memglodesc{(\ref {rand.util.canonical})}} {\memgloref{}}|memjustarg}{1426} -\glossaryentry{rand.dist@ {\memgloterm{rand.dist}}{\memglodesc{(\ref {rand.dist})}} {\memgloref{}}|memjustarg}{1426} -\glossaryentry{rand.dist.general@ {\memgloterm{rand.dist.general}}{\memglodesc{(\ref {rand.dist.general})}} {\memgloref{}}|memjustarg}{1426} -\glossaryentry{rand.dist.uni@ {\memgloterm{rand.dist.uni}}{\memglodesc{(\ref {rand.dist.uni})}} {\memgloref{}}|memjustarg}{1426} -\glossaryentry{rand.dist.uni.int@ {\memgloterm{rand.dist.uni.int}}{\memglodesc{(\ref {rand.dist.uni.int})}} {\memgloref{}}|memjustarg}{1426} -\glossaryentry{rand.dist.uni.real@ {\memgloterm{rand.dist.uni.real}}{\memglodesc{(\ref {rand.dist.uni.real})}} {\memgloref{}}|memjustarg}{1427} -\glossaryentry{rand.dist.bern@ {\memgloterm{rand.dist.bern}}{\memglodesc{(\ref {rand.dist.bern})}} {\memgloref{}}|memjustarg}{1428} -\glossaryentry{rand.dist.bern.bernoulli@ {\memgloterm{rand.dist.bern.bernoulli}}{\memglodesc{(\ref {rand.dist.bern.bernoulli})}} {\memgloref{}}|memjustarg}{1428} -\glossaryentry{rand.dist.bern.bin@ {\memgloterm{rand.dist.bern.bin}}{\memglodesc{(\ref {rand.dist.bern.bin})}} {\memgloref{}}|memjustarg}{1429} -\glossaryentry{rand.dist.bern.geo@ {\memgloterm{rand.dist.bern.geo}}{\memglodesc{(\ref {rand.dist.bern.geo})}} {\memgloref{}}|memjustarg}{1430} -\glossaryentry{rand.dist.bern.negbin@ {\memgloterm{rand.dist.bern.negbin}}{\memglodesc{(\ref {rand.dist.bern.negbin})}} {\memgloref{}}|memjustarg}{1431} -\glossaryentry{rand.dist.pois@ {\memgloterm{rand.dist.pois}}{\memglodesc{(\ref {rand.dist.pois})}} {\memgloref{}}|memjustarg}{1432} -\glossaryentry{rand.dist.pois.poisson@ {\memgloterm{rand.dist.pois.poisson}}{\memglodesc{(\ref {rand.dist.pois.poisson})}} {\memgloref{}}|memjustarg}{1432} -\glossaryentry{rand.dist.pois.exp@ {\memgloterm{rand.dist.pois.exp}}{\memglodesc{(\ref {rand.dist.pois.exp})}} {\memgloref{}}|memjustarg}{1433} -\glossaryentry{rand.dist.pois.gamma@ {\memgloterm{rand.dist.pois.gamma}}{\memglodesc{(\ref {rand.dist.pois.gamma})}} {\memgloref{}}|memjustarg}{1434} -\glossaryentry{rand.dist.pois.weibull@ {\memgloterm{rand.dist.pois.weibull}}{\memglodesc{(\ref {rand.dist.pois.weibull})}} {\memgloref{}}|memjustarg}{1435} -\glossaryentry{rand.dist.pois.extreme@ {\memgloterm{rand.dist.pois.extreme}}{\memglodesc{(\ref {rand.dist.pois.extreme})}} {\memgloref{}}|memjustarg}{1436} -\glossaryentry{rand.dist.norm@ {\memgloterm{rand.dist.norm}}{\memglodesc{(\ref {rand.dist.norm})}} {\memgloref{}}|memjustarg}{1437} -\glossaryentry{rand.dist.norm.normal@ {\memgloterm{rand.dist.norm.normal}}{\memglodesc{(\ref {rand.dist.norm.normal})}} {\memgloref{}}|memjustarg}{1437} -\glossaryentry{rand.dist.norm.lognormal@ {\memgloterm{rand.dist.norm.lognormal}}{\memglodesc{(\ref {rand.dist.norm.lognormal})}} {\memgloref{}}|memjustarg}{1438} -\glossaryentry{rand.dist.norm.chisq@ {\memgloterm{rand.dist.norm.chisq}}{\memglodesc{(\ref {rand.dist.norm.chisq})}} {\memgloref{}}|memjustarg}{1439} -\glossaryentry{rand.dist.norm.cauchy@ {\memgloterm{rand.dist.norm.cauchy}}{\memglodesc{(\ref {rand.dist.norm.cauchy})}} {\memgloref{}}|memjustarg}{1439} -\glossaryentry{rand.dist.norm.f@ {\memgloterm{rand.dist.norm.f}}{\memglodesc{(\ref {rand.dist.norm.f})}} {\memgloref{}}|memjustarg}{1440} -\glossaryentry{rand.dist.norm.t@ {\memgloterm{rand.dist.norm.t}}{\memglodesc{(\ref {rand.dist.norm.t})}} {\memgloref{}}|memjustarg}{1441} -\glossaryentry{rand.dist.samp@ {\memgloterm{rand.dist.samp}}{\memglodesc{(\ref {rand.dist.samp})}} {\memgloref{}}|memjustarg}{1442} -\glossaryentry{rand.dist.samp.discrete@ {\memgloterm{rand.dist.samp.discrete}}{\memglodesc{(\ref {rand.dist.samp.discrete})}} {\memgloref{}}|memjustarg}{1442} -\glossaryentry{rand.dist.samp.pconst@ {\memgloterm{rand.dist.samp.pconst}}{\memglodesc{(\ref {rand.dist.samp.pconst})}} {\memgloref{}}|memjustarg}{1444} -\glossaryentry{rand.dist.samp.plinear@ {\memgloterm{rand.dist.samp.plinear}}{\memglodesc{(\ref {rand.dist.samp.plinear})}} {\memgloref{}}|memjustarg}{1445} -\glossaryentry{c.math.rand@ {\memgloterm{c.math.rand}}{\memglodesc{(\ref {c.math.rand})}} {\memgloref{}}|memjustarg}{1447} -\glossaryentry{numarray@ {\memgloterm{numarray}}{\memglodesc{(\ref {numarray})}} {\memgloref{}}|memjustarg}{1447} -\glossaryentry{valarray.syn@ {\memgloterm{valarray.syn}}{\memglodesc{(\ref {valarray.syn})}} {\memgloref{}}|memjustarg}{1447} -\glossaryentry{template.valarray@ {\memgloterm{template.valarray}}{\memglodesc{(\ref {template.valarray})}} {\memgloref{}}|memjustarg}{1450} -\glossaryentry{template.valarray.overview@ {\memgloterm{template.valarray.overview}}{\memglodesc{(\ref {template.valarray.overview})}} {\memgloref{}}|memjustarg}{1450} -\glossaryentry{valarray.cons@ {\memgloterm{valarray.cons}}{\memglodesc{(\ref {valarray.cons})}} {\memgloref{}}|memjustarg}{1452} -\glossaryentry{valarray.assign@ {\memgloterm{valarray.assign}}{\memglodesc{(\ref {valarray.assign})}} {\memgloref{}}|memjustarg}{1453} -\glossaryentry{valarray.access@ {\memgloterm{valarray.access}}{\memglodesc{(\ref {valarray.access})}} {\memgloref{}}|memjustarg}{1453} -\glossaryentry{valarray.sub@ {\memgloterm{valarray.sub}}{\memglodesc{(\ref {valarray.sub})}} {\memgloref{}}|memjustarg}{1453} -\glossaryentry{valarray.unary@ {\memgloterm{valarray.unary}}{\memglodesc{(\ref {valarray.unary})}} {\memgloref{}}|memjustarg}{1455} -\glossaryentry{valarray.cassign@ {\memgloterm{valarray.cassign}}{\memglodesc{(\ref {valarray.cassign})}} {\memgloref{}}|memjustarg}{1455} -\glossaryentry{valarray.members@ {\memgloterm{valarray.members}}{\memglodesc{(\ref {valarray.members})}} {\memgloref{}}|memjustarg}{1456} -\glossaryentry{valarray.nonmembers@ {\memgloterm{valarray.nonmembers}}{\memglodesc{(\ref {valarray.nonmembers})}} {\memgloref{}}|memjustarg}{1457} -\glossaryentry{valarray.binary@ {\memgloterm{valarray.binary}}{\memglodesc{(\ref {valarray.binary})}} {\memgloref{}}|memjustarg}{1457} -\glossaryentry{valarray.comparison@ {\memgloterm{valarray.comparison}}{\memglodesc{(\ref {valarray.comparison})}} {\memgloref{}}|memjustarg}{1458} -\glossaryentry{valarray.transcend@ {\memgloterm{valarray.transcend}}{\memglodesc{(\ref {valarray.transcend})}} {\memgloref{}}|memjustarg}{1459} -\glossaryentry{valarray.special@ {\memgloterm{valarray.special}}{\memglodesc{(\ref {valarray.special})}} {\memgloref{}}|memjustarg}{1459} -\glossaryentry{class.slice@ {\memgloterm{class.slice}}{\memglodesc{(\ref {class.slice})}} {\memgloref{}}|memjustarg}{1459} -\glossaryentry{class.slice.overview@ {\memgloterm{class.slice.overview}}{\memglodesc{(\ref {class.slice.overview})}} {\memgloref{}}|memjustarg}{1459} -\glossaryentry{cons.slice@ {\memgloterm{cons.slice}}{\memglodesc{(\ref {cons.slice})}} {\memgloref{}}|memjustarg}{1460} -\glossaryentry{slice.access@ {\memgloterm{slice.access}}{\memglodesc{(\ref {slice.access})}} {\memgloref{}}|memjustarg}{1460} -\glossaryentry{slice.ops@ {\memgloterm{slice.ops}}{\memglodesc{(\ref {slice.ops})}} {\memgloref{}}|memjustarg}{1460} -\glossaryentry{template.slice.array@ {\memgloterm{template.slice.array}}{\memglodesc{(\ref {template.slice.array})}} {\memgloref{}}|memjustarg}{1460} -\glossaryentry{template.slice.array.overview@ {\memgloterm{template.slice.array.overview}}{\memglodesc{(\ref {template.slice.array.overview})}} {\memgloref{}}|memjustarg}{1460} -\glossaryentry{slice.arr.assign@ {\memgloterm{slice.arr.assign}}{\memglodesc{(\ref {slice.arr.assign})}} {\memgloref{}}|memjustarg}{1461} -\glossaryentry{slice.arr.comp.assign@ {\memgloterm{slice.arr.comp.assign}}{\memglodesc{(\ref {slice.arr.comp.assign})}} {\memgloref{}}|memjustarg}{1461} -\glossaryentry{slice.arr.fill@ {\memgloterm{slice.arr.fill}}{\memglodesc{(\ref {slice.arr.fill})}} {\memgloref{}}|memjustarg}{1461} -\glossaryentry{class.gslice@ {\memgloterm{class.gslice}}{\memglodesc{(\ref {class.gslice})}} {\memgloref{}}|memjustarg}{1461} -\glossaryentry{class.gslice.overview@ {\memgloterm{class.gslice.overview}}{\memglodesc{(\ref {class.gslice.overview})}} {\memgloref{}}|memjustarg}{1461} -\glossaryentry{gslice.cons@ {\memgloterm{gslice.cons}}{\memglodesc{(\ref {gslice.cons})}} {\memgloref{}}|memjustarg}{1462} -\glossaryentry{gslice.access@ {\memgloterm{gslice.access}}{\memglodesc{(\ref {gslice.access})}} {\memgloref{}}|memjustarg}{1462} -\glossaryentry{template.gslice.array@ {\memgloterm{template.gslice.array}}{\memglodesc{(\ref {template.gslice.array})}} {\memgloref{}}|memjustarg}{1463} -\glossaryentry{template.gslice.array.overview@ {\memgloterm{template.gslice.array.overview}}{\memglodesc{(\ref {template.gslice.array.overview})}} {\memgloref{}}|memjustarg}{1463} -\glossaryentry{gslice.array.assign@ {\memgloterm{gslice.array.assign}}{\memglodesc{(\ref {gslice.array.assign})}} {\memgloref{}}|memjustarg}{1463} -\glossaryentry{gslice.array.comp.assign@ {\memgloterm{gslice.array.comp.assign}}{\memglodesc{(\ref {gslice.array.comp.assign})}} {\memgloref{}}|memjustarg}{1463} -\glossaryentry{gslice.array.fill@ {\memgloterm{gslice.array.fill}}{\memglodesc{(\ref {gslice.array.fill})}} {\memgloref{}}|memjustarg}{1463} -\glossaryentry{template.mask.array@ {\memgloterm{template.mask.array}}{\memglodesc{(\ref {template.mask.array})}} {\memgloref{}}|memjustarg}{1464} -\glossaryentry{template.mask.array.overview@ {\memgloterm{template.mask.array.overview}}{\memglodesc{(\ref {template.mask.array.overview})}} {\memgloref{}}|memjustarg}{1464} -\glossaryentry{mask.array.assign@ {\memgloterm{mask.array.assign}}{\memglodesc{(\ref {mask.array.assign})}} {\memgloref{}}|memjustarg}{1464} -\glossaryentry{mask.array.comp.assign@ {\memgloterm{mask.array.comp.assign}}{\memglodesc{(\ref {mask.array.comp.assign})}} {\memgloref{}}|memjustarg}{1464} -\glossaryentry{mask.array.fill@ {\memgloterm{mask.array.fill}}{\memglodesc{(\ref {mask.array.fill})}} {\memgloref{}}|memjustarg}{1464} -\glossaryentry{template.indirect.array@ {\memgloterm{template.indirect.array}}{\memglodesc{(\ref {template.indirect.array})}} {\memgloref{}}|memjustarg}{1465} -\glossaryentry{template.indirect.array.overview@ {\memgloterm{template.indirect.array.overview}}{\memglodesc{(\ref {template.indirect.array.overview})}} {\memgloref{}}|memjustarg}{1465} -\glossaryentry{indirect.array.assign@ {\memgloterm{indirect.array.assign}}{\memglodesc{(\ref {indirect.array.assign})}} {\memgloref{}}|memjustarg}{1465} -\glossaryentry{indirect.array.comp.assign@ {\memgloterm{indirect.array.comp.assign}}{\memglodesc{(\ref {indirect.array.comp.assign})}} {\memgloref{}}|memjustarg}{1465} -\glossaryentry{indirect.array.fill@ {\memgloterm{indirect.array.fill}}{\memglodesc{(\ref {indirect.array.fill})}} {\memgloref{}}|memjustarg}{1466} -\glossaryentry{valarray.range@ {\memgloterm{valarray.range}}{\memglodesc{(\ref {valarray.range})}} {\memgloref{}}|memjustarg}{1466} -\glossaryentry{c.math@ {\memgloterm{c.math}}{\memglodesc{(\ref {c.math})}} {\memgloref{}}|memjustarg}{1466} -\glossaryentry{cmath.syn@ {\memgloterm{cmath.syn}}{\memglodesc{(\ref {cmath.syn})}} {\memgloref{}}|memjustarg}{1466} -\glossaryentry{c.math.abs@ {\memgloterm{c.math.abs}}{\memglodesc{(\ref {c.math.abs})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{c.math.hypot3@ {\memgloterm{c.math.hypot3}}{\memglodesc{(\ref {c.math.hypot3})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{c.math.lerp@ {\memgloterm{c.math.lerp}}{\memglodesc{(\ref {c.math.lerp})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{c.math.fpclass@ {\memgloterm{c.math.fpclass}}{\memglodesc{(\ref {c.math.fpclass})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{sf.cmath@ {\memgloterm{sf.cmath}}{\memglodesc{(\ref {sf.cmath})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{sf.cmath.general@ {\memgloterm{sf.cmath.general}}{\memglodesc{(\ref {sf.cmath.general})}} {\memgloref{}}|memjustarg}{1473} -\glossaryentry{sf.cmath.assoc.laguerre@ {\memgloterm{sf.cmath.assoc.laguerre}}{\memglodesc{(\ref {sf.cmath.assoc.laguerre})}} {\memgloref{}}|memjustarg}{1474} -\glossaryentry{sf.cmath.assoc.legendre@ {\memgloterm{sf.cmath.assoc.legendre}}{\memglodesc{(\ref {sf.cmath.assoc.legendre})}} {\memgloref{}}|memjustarg}{1474} -\glossaryentry{sf.cmath.beta@ {\memgloterm{sf.cmath.beta}}{\memglodesc{(\ref {sf.cmath.beta})}} {\memgloref{}}|memjustarg}{1474} -\glossaryentry{sf.cmath.comp.ellint.1@ {\memgloterm{sf.cmath.comp.ellint.1}}{\memglodesc{(\ref {sf.cmath.comp.ellint.1})}} {\memgloref{}}|memjustarg}{1474} -\glossaryentry{sf.cmath.comp.ellint.2@ {\memgloterm{sf.cmath.comp.ellint.2}}{\memglodesc{(\ref {sf.cmath.comp.ellint.2})}} {\memgloref{}}|memjustarg}{1475} -\glossaryentry{sf.cmath.comp.ellint.3@ {\memgloterm{sf.cmath.comp.ellint.3}}{\memglodesc{(\ref {sf.cmath.comp.ellint.3})}} {\memgloref{}}|memjustarg}{1475} -\glossaryentry{sf.cmath.cyl.bessel.i@ {\memgloterm{sf.cmath.cyl.bessel.i}}{\memglodesc{(\ref {sf.cmath.cyl.bessel.i})}} {\memgloref{}}|memjustarg}{1475} -\glossaryentry{sf.cmath.cyl.bessel.j@ {\memgloterm{sf.cmath.cyl.bessel.j}}{\memglodesc{(\ref {sf.cmath.cyl.bessel.j})}} {\memgloref{}}|memjustarg}{1475} -\glossaryentry{sf.cmath.cyl.bessel.k@ {\memgloterm{sf.cmath.cyl.bessel.k}}{\memglodesc{(\ref {sf.cmath.cyl.bessel.k})}} {\memgloref{}}|memjustarg}{1476} -\glossaryentry{sf.cmath.cyl.neumann@ {\memgloterm{sf.cmath.cyl.neumann}}{\memglodesc{(\ref {sf.cmath.cyl.neumann})}} {\memgloref{}}|memjustarg}{1476} -\glossaryentry{sf.cmath.ellint.1@ {\memgloterm{sf.cmath.ellint.1}}{\memglodesc{(\ref {sf.cmath.ellint.1})}} {\memgloref{}}|memjustarg}{1476} -\glossaryentry{sf.cmath.ellint.2@ {\memgloterm{sf.cmath.ellint.2}}{\memglodesc{(\ref {sf.cmath.ellint.2})}} {\memgloref{}}|memjustarg}{1476} -\glossaryentry{sf.cmath.ellint.3@ {\memgloterm{sf.cmath.ellint.3}}{\memglodesc{(\ref {sf.cmath.ellint.3})}} {\memgloref{}}|memjustarg}{1477} -\glossaryentry{sf.cmath.expint@ {\memgloterm{sf.cmath.expint}}{\memglodesc{(\ref {sf.cmath.expint})}} {\memgloref{}}|memjustarg}{1477} -\glossaryentry{sf.cmath.hermite@ {\memgloterm{sf.cmath.hermite}}{\memglodesc{(\ref {sf.cmath.hermite})}} {\memgloref{}}|memjustarg}{1477} -\glossaryentry{sf.cmath.laguerre@ {\memgloterm{sf.cmath.laguerre}}{\memglodesc{(\ref {sf.cmath.laguerre})}} {\memgloref{}}|memjustarg}{1477} -\glossaryentry{sf.cmath.legendre@ {\memgloterm{sf.cmath.legendre}}{\memglodesc{(\ref {sf.cmath.legendre})}} {\memgloref{}}|memjustarg}{1477} -\glossaryentry{sf.cmath.riemann.zeta@ {\memgloterm{sf.cmath.riemann.zeta}}{\memglodesc{(\ref {sf.cmath.riemann.zeta})}} {\memgloref{}}|memjustarg}{1478} -\glossaryentry{sf.cmath.sph.bessel@ {\memgloterm{sf.cmath.sph.bessel}}{\memglodesc{(\ref {sf.cmath.sph.bessel})}} {\memgloref{}}|memjustarg}{1478} -\glossaryentry{sf.cmath.sph.legendre@ {\memgloterm{sf.cmath.sph.legendre}}{\memglodesc{(\ref {sf.cmath.sph.legendre})}} {\memgloref{}}|memjustarg}{1478} -\glossaryentry{sf.cmath.sph.neumann@ {\memgloterm{sf.cmath.sph.neumann}}{\memglodesc{(\ref {sf.cmath.sph.neumann})}} {\memgloref{}}|memjustarg}{1478} -\glossaryentry{numbers@ {\memgloterm{numbers}}{\memglodesc{(\ref {numbers})}} {\memgloref{}}|memjustarg}{1479} -\glossaryentry{numbers.syn@ {\memgloterm{numbers.syn}}{\memglodesc{(\ref {numbers.syn})}} {\memgloref{}}|memjustarg}{1479} -\glossaryentry{math.constants@ {\memgloterm{math.constants}}{\memglodesc{(\ref {math.constants})}} {\memgloref{}}|memjustarg}{1479} -\glossaryentry{time@ {\memgloterm{time}}{\memglodesc{(\ref {time})}} {\memgloref{}}|memjustarg}{1480} -\glossaryentry{time.general@ {\memgloterm{time.general}}{\memglodesc{(\ref {time.general})}} {\memgloref{}}|memjustarg}{1480} -\glossaryentry{time.syn@ {\memgloterm{time.syn}}{\memglodesc{(\ref {time.syn})}} {\memgloref{}}|memjustarg}{1480} -\glossaryentry{time.clock.req@ {\memgloterm{time.clock.req}}{\memglodesc{(\ref {time.clock.req})}} {\memgloref{}}|memjustarg}{1494} -\glossaryentry{time.traits@ {\memgloterm{time.traits}}{\memglodesc{(\ref {time.traits})}} {\memgloref{}}|memjustarg}{1495} -\glossaryentry{time.traits.is.fp@ {\memgloterm{time.traits.is.fp}}{\memglodesc{(\ref {time.traits.is.fp})}} {\memgloref{}}|memjustarg}{1495} -\glossaryentry{time.traits.duration.values@ {\memgloterm{time.traits.duration.values}}{\memglodesc{(\ref {time.traits.duration.values})}} {\memgloref{}}|memjustarg}{1495} -\glossaryentry{time.traits.specializations@ {\memgloterm{time.traits.specializations}}{\memglodesc{(\ref {time.traits.specializations})}} {\memgloref{}}|memjustarg}{1495} -\glossaryentry{time.traits.is.clock@ {\memgloterm{time.traits.is.clock}}{\memglodesc{(\ref {time.traits.is.clock})}} {\memgloref{}}|memjustarg}{1496} -\glossaryentry{time.duration@ {\memgloterm{time.duration}}{\memglodesc{(\ref {time.duration})}} {\memgloref{}}|memjustarg}{1496} -\glossaryentry{time.duration.general@ {\memgloterm{time.duration.general}}{\memglodesc{(\ref {time.duration.general})}} {\memgloref{}}|memjustarg}{1496} -\glossaryentry{time.duration.cons@ {\memgloterm{time.duration.cons}}{\memglodesc{(\ref {time.duration.cons})}} {\memgloref{}}|memjustarg}{1497} -\glossaryentry{time.duration.observer@ {\memgloterm{time.duration.observer}}{\memglodesc{(\ref {time.duration.observer})}} {\memgloref{}}|memjustarg}{1498} -\glossaryentry{time.duration.arithmetic@ {\memgloterm{time.duration.arithmetic}}{\memglodesc{(\ref {time.duration.arithmetic})}} {\memgloref{}}|memjustarg}{1498} -\glossaryentry{time.duration.special@ {\memgloterm{time.duration.special}}{\memglodesc{(\ref {time.duration.special})}} {\memgloref{}}|memjustarg}{1498} -\glossaryentry{time.duration.nonmember@ {\memgloterm{time.duration.nonmember}}{\memglodesc{(\ref {time.duration.nonmember})}} {\memgloref{}}|memjustarg}{1499} -\glossaryentry{time.duration.comparisons@ {\memgloterm{time.duration.comparisons}}{\memglodesc{(\ref {time.duration.comparisons})}} {\memgloref{}}|memjustarg}{1500} -\glossaryentry{time.duration.cast@ {\memgloterm{time.duration.cast}}{\memglodesc{(\ref {time.duration.cast})}} {\memgloref{}}|memjustarg}{1500} -\glossaryentry{time.duration.literals@ {\memgloterm{time.duration.literals}}{\memglodesc{(\ref {time.duration.literals})}} {\memgloref{}}|memjustarg}{1501} -\glossaryentry{time.duration.alg@ {\memgloterm{time.duration.alg}}{\memglodesc{(\ref {time.duration.alg})}} {\memgloref{}}|memjustarg}{1502} -\glossaryentry{time.duration.io@ {\memgloterm{time.duration.io}}{\memglodesc{(\ref {time.duration.io})}} {\memgloref{}}|memjustarg}{1502} -\glossaryentry{time.point@ {\memgloterm{time.point}}{\memglodesc{(\ref {time.point})}} {\memgloref{}}|memjustarg}{1503} -\glossaryentry{time.point.general@ {\memgloterm{time.point.general}}{\memglodesc{(\ref {time.point.general})}} {\memgloref{}}|memjustarg}{1503} -\glossaryentry{time.point.cons@ {\memgloterm{time.point.cons}}{\memglodesc{(\ref {time.point.cons})}} {\memgloref{}}|memjustarg}{1503} -\glossaryentry{time.point.observer@ {\memgloterm{time.point.observer}}{\memglodesc{(\ref {time.point.observer})}} {\memgloref{}}|memjustarg}{1504} -\glossaryentry{time.point.arithmetic@ {\memgloterm{time.point.arithmetic}}{\memglodesc{(\ref {time.point.arithmetic})}} {\memgloref{}}|memjustarg}{1504} -\glossaryentry{time.point.special@ {\memgloterm{time.point.special}}{\memglodesc{(\ref {time.point.special})}} {\memgloref{}}|memjustarg}{1504} -\glossaryentry{time.point.nonmember@ {\memgloterm{time.point.nonmember}}{\memglodesc{(\ref {time.point.nonmember})}} {\memgloref{}}|memjustarg}{1504} -\glossaryentry{time.point.comparisons@ {\memgloterm{time.point.comparisons}}{\memglodesc{(\ref {time.point.comparisons})}} {\memgloref{}}|memjustarg}{1505} -\glossaryentry{time.point.cast@ {\memgloterm{time.point.cast}}{\memglodesc{(\ref {time.point.cast})}} {\memgloref{}}|memjustarg}{1505} -\glossaryentry{time.clock@ {\memgloterm{time.clock}}{\memglodesc{(\ref {time.clock})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.general@ {\memgloterm{time.clock.general}}{\memglodesc{(\ref {time.clock.general})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.system@ {\memgloterm{time.clock.system}}{\memglodesc{(\ref {time.clock.system})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.system.overview@ {\memgloterm{time.clock.system.overview}}{\memglodesc{(\ref {time.clock.system.overview})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.system.members@ {\memgloterm{time.clock.system.members}}{\memglodesc{(\ref {time.clock.system.members})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.system.nonmembers@ {\memgloterm{time.clock.system.nonmembers}}{\memglodesc{(\ref {time.clock.system.nonmembers})}} {\memgloref{}}|memjustarg}{1506} -\glossaryentry{time.clock.utc@ {\memgloterm{time.clock.utc}}{\memglodesc{(\ref {time.clock.utc})}} {\memgloref{}}|memjustarg}{1507} -\glossaryentry{time.clock.utc.overview@ {\memgloterm{time.clock.utc.overview}}{\memglodesc{(\ref {time.clock.utc.overview})}} {\memgloref{}}|memjustarg}{1507} -\glossaryentry{time.clock.utc.members@ {\memgloterm{time.clock.utc.members}}{\memglodesc{(\ref {time.clock.utc.members})}} {\memgloref{}}|memjustarg}{1508} -\glossaryentry{time.clock.utc.nonmembers@ {\memgloterm{time.clock.utc.nonmembers}}{\memglodesc{(\ref {time.clock.utc.nonmembers})}} {\memgloref{}}|memjustarg}{1508} -\glossaryentry{time.clock.tai@ {\memgloterm{time.clock.tai}}{\memglodesc{(\ref {time.clock.tai})}} {\memgloref{}}|memjustarg}{1509} -\glossaryentry{time.clock.tai.overview@ {\memgloterm{time.clock.tai.overview}}{\memglodesc{(\ref {time.clock.tai.overview})}} {\memgloref{}}|memjustarg}{1509} -\glossaryentry{time.clock.tai.members@ {\memgloterm{time.clock.tai.members}}{\memglodesc{(\ref {time.clock.tai.members})}} {\memgloref{}}|memjustarg}{1510} -\glossaryentry{time.clock.tai.nonmembers@ {\memgloterm{time.clock.tai.nonmembers}}{\memglodesc{(\ref {time.clock.tai.nonmembers})}} {\memgloref{}}|memjustarg}{1510} -\glossaryentry{time.clock.gps@ {\memgloterm{time.clock.gps}}{\memglodesc{(\ref {time.clock.gps})}} {\memgloref{}}|memjustarg}{1511} -\glossaryentry{time.clock.gps.overview@ {\memgloterm{time.clock.gps.overview}}{\memglodesc{(\ref {time.clock.gps.overview})}} {\memgloref{}}|memjustarg}{1511} -\glossaryentry{time.clock.gps.members@ {\memgloterm{time.clock.gps.members}}{\memglodesc{(\ref {time.clock.gps.members})}} {\memgloref{}}|memjustarg}{1511} -\glossaryentry{time.clock.gps.nonmembers@ {\memgloterm{time.clock.gps.nonmembers}}{\memglodesc{(\ref {time.clock.gps.nonmembers})}} {\memgloref{}}|memjustarg}{1511} -\glossaryentry{time.clock.file@ {\memgloterm{time.clock.file}}{\memglodesc{(\ref {time.clock.file})}} {\memgloref{}}|memjustarg}{1512} -\glossaryentry{time.clock.file.overview@ {\memgloterm{time.clock.file.overview}}{\memglodesc{(\ref {time.clock.file.overview})}} {\memgloref{}}|memjustarg}{1512} -\glossaryentry{time.clock.file.members@ {\memgloterm{time.clock.file.members}}{\memglodesc{(\ref {time.clock.file.members})}} {\memgloref{}}|memjustarg}{1512} -\glossaryentry{time.clock.file.nonmembers@ {\memgloterm{time.clock.file.nonmembers}}{\memglodesc{(\ref {time.clock.file.nonmembers})}} {\memgloref{}}|memjustarg}{1513} -\glossaryentry{time.clock.steady@ {\memgloterm{time.clock.steady}}{\memglodesc{(\ref {time.clock.steady})}} {\memgloref{}}|memjustarg}{1513} -\glossaryentry{time.clock.hires@ {\memgloterm{time.clock.hires}}{\memglodesc{(\ref {time.clock.hires})}} {\memgloref{}}|memjustarg}{1513} -\glossaryentry{time.clock.local@ {\memgloterm{time.clock.local}}{\memglodesc{(\ref {time.clock.local})}} {\memgloref{}}|memjustarg}{1513} -\glossaryentry{time.clock.cast@ {\memgloterm{time.clock.cast}}{\memglodesc{(\ref {time.clock.cast})}} {\memgloref{}}|memjustarg}{1514} -\glossaryentry{time.clock.conv@ {\memgloterm{time.clock.conv}}{\memglodesc{(\ref {time.clock.conv})}} {\memgloref{}}|memjustarg}{1514} -\glossaryentry{time.clock.cast.id@ {\memgloterm{time.clock.cast.id}}{\memglodesc{(\ref {time.clock.cast.id})}} {\memgloref{}}|memjustarg}{1514} -\glossaryentry{time.clock.cast.sys.utc@ {\memgloterm{time.clock.cast.sys.utc}}{\memglodesc{(\ref {time.clock.cast.sys.utc})}} {\memgloref{}}|memjustarg}{1515} -\glossaryentry{time.clock.cast.sys@ {\memgloterm{time.clock.cast.sys}}{\memglodesc{(\ref {time.clock.cast.sys})}} {\memgloref{}}|memjustarg}{1515} -\glossaryentry{time.clock.cast.utc@ {\memgloterm{time.clock.cast.utc}}{\memglodesc{(\ref {time.clock.cast.utc})}} {\memgloref{}}|memjustarg}{1516} -\glossaryentry{time.clock.cast.fn@ {\memgloterm{time.clock.cast.fn}}{\memglodesc{(\ref {time.clock.cast.fn})}} {\memgloref{}}|memjustarg}{1516} -\glossaryentry{time.cal@ {\memgloterm{time.cal}}{\memglodesc{(\ref {time.cal})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.general@ {\memgloterm{time.cal.general}}{\memglodesc{(\ref {time.cal.general})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.last@ {\memgloterm{time.cal.last}}{\memglodesc{(\ref {time.cal.last})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.day@ {\memgloterm{time.cal.day}}{\memglodesc{(\ref {time.cal.day})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.day.overview@ {\memgloterm{time.cal.day.overview}}{\memglodesc{(\ref {time.cal.day.overview})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.day.members@ {\memgloterm{time.cal.day.members}}{\memglodesc{(\ref {time.cal.day.members})}} {\memgloref{}}|memjustarg}{1517} -\glossaryentry{time.cal.day.nonmembers@ {\memgloterm{time.cal.day.nonmembers}}{\memglodesc{(\ref {time.cal.day.nonmembers})}} {\memgloref{}}|memjustarg}{1518} -\glossaryentry{time.cal.month@ {\memgloterm{time.cal.month}}{\memglodesc{(\ref {time.cal.month})}} {\memgloref{}}|memjustarg}{1519} -\glossaryentry{time.cal.month.overview@ {\memgloterm{time.cal.month.overview}}{\memglodesc{(\ref {time.cal.month.overview})}} {\memgloref{}}|memjustarg}{1519} -\glossaryentry{time.cal.month.members@ {\memgloterm{time.cal.month.members}}{\memglodesc{(\ref {time.cal.month.members})}} {\memgloref{}}|memjustarg}{1519} -\glossaryentry{time.cal.month.nonmembers@ {\memgloterm{time.cal.month.nonmembers}}{\memglodesc{(\ref {time.cal.month.nonmembers})}} {\memgloref{}}|memjustarg}{1520} -\glossaryentry{time.cal.year@ {\memgloterm{time.cal.year}}{\memglodesc{(\ref {time.cal.year})}} {\memgloref{}}|memjustarg}{1521} -\glossaryentry{time.cal.year.overview@ {\memgloterm{time.cal.year.overview}}{\memglodesc{(\ref {time.cal.year.overview})}} {\memgloref{}}|memjustarg}{1521} -\glossaryentry{time.cal.year.members@ {\memgloterm{time.cal.year.members}}{\memglodesc{(\ref {time.cal.year.members})}} {\memgloref{}}|memjustarg}{1521} -\glossaryentry{time.cal.year.nonmembers@ {\memgloterm{time.cal.year.nonmembers}}{\memglodesc{(\ref {time.cal.year.nonmembers})}} {\memgloref{}}|memjustarg}{1522} -\glossaryentry{time.cal.wd@ {\memgloterm{time.cal.wd}}{\memglodesc{(\ref {time.cal.wd})}} {\memgloref{}}|memjustarg}{1523} -\glossaryentry{time.cal.wd.overview@ {\memgloterm{time.cal.wd.overview}}{\memglodesc{(\ref {time.cal.wd.overview})}} {\memgloref{}}|memjustarg}{1523} -\glossaryentry{time.cal.wd.members@ {\memgloterm{time.cal.wd.members}}{\memglodesc{(\ref {time.cal.wd.members})}} {\memgloref{}}|memjustarg}{1524} -\glossaryentry{time.cal.wd.nonmembers@ {\memgloterm{time.cal.wd.nonmembers}}{\memglodesc{(\ref {time.cal.wd.nonmembers})}} {\memgloref{}}|memjustarg}{1525} -\glossaryentry{time.cal.wdidx@ {\memgloterm{time.cal.wdidx}}{\memglodesc{(\ref {time.cal.wdidx})}} {\memgloref{}}|memjustarg}{1525} -\glossaryentry{time.cal.wdidx.overview@ {\memgloterm{time.cal.wdidx.overview}}{\memglodesc{(\ref {time.cal.wdidx.overview})}} {\memgloref{}}|memjustarg}{1525} -\glossaryentry{time.cal.wdidx.members@ {\memgloterm{time.cal.wdidx.members}}{\memglodesc{(\ref {time.cal.wdidx.members})}} {\memgloref{}}|memjustarg}{1526} -\glossaryentry{time.cal.wdidx.nonmembers@ {\memgloterm{time.cal.wdidx.nonmembers}}{\memglodesc{(\ref {time.cal.wdidx.nonmembers})}} {\memgloref{}}|memjustarg}{1526} -\glossaryentry{time.cal.wdlast@ {\memgloterm{time.cal.wdlast}}{\memglodesc{(\ref {time.cal.wdlast})}} {\memgloref{}}|memjustarg}{1526} -\glossaryentry{time.cal.wdlast.overview@ {\memgloterm{time.cal.wdlast.overview}}{\memglodesc{(\ref {time.cal.wdlast.overview})}} {\memgloref{}}|memjustarg}{1526} -\glossaryentry{time.cal.wdlast.members@ {\memgloterm{time.cal.wdlast.members}}{\memglodesc{(\ref {time.cal.wdlast.members})}} {\memgloref{}}|memjustarg}{1527} -\glossaryentry{time.cal.wdlast.nonmembers@ {\memgloterm{time.cal.wdlast.nonmembers}}{\memglodesc{(\ref {time.cal.wdlast.nonmembers})}} {\memgloref{}}|memjustarg}{1527} -\glossaryentry{time.cal.md@ {\memgloterm{time.cal.md}}{\memglodesc{(\ref {time.cal.md})}} {\memgloref{}}|memjustarg}{1527} -\glossaryentry{time.cal.md.overview@ {\memgloterm{time.cal.md.overview}}{\memglodesc{(\ref {time.cal.md.overview})}} {\memgloref{}}|memjustarg}{1527} -\glossaryentry{time.cal.md.members@ {\memgloterm{time.cal.md.members}}{\memglodesc{(\ref {time.cal.md.members})}} {\memgloref{}}|memjustarg}{1527} -\glossaryentry{time.cal.md.nonmembers@ {\memgloterm{time.cal.md.nonmembers}}{\memglodesc{(\ref {time.cal.md.nonmembers})}} {\memgloref{}}|memjustarg}{1528} -\glossaryentry{time.cal.mdlast@ {\memgloterm{time.cal.mdlast}}{\memglodesc{(\ref {time.cal.mdlast})}} {\memgloref{}}|memjustarg}{1528} -\glossaryentry{time.cal.mwd@ {\memgloterm{time.cal.mwd}}{\memglodesc{(\ref {time.cal.mwd})}} {\memgloref{}}|memjustarg}{1529} -\glossaryentry{time.cal.mwd.overview@ {\memgloterm{time.cal.mwd.overview}}{\memglodesc{(\ref {time.cal.mwd.overview})}} {\memgloref{}}|memjustarg}{1529} -\glossaryentry{time.cal.mwd.members@ {\memgloterm{time.cal.mwd.members}}{\memglodesc{(\ref {time.cal.mwd.members})}} {\memgloref{}}|memjustarg}{1529} -\glossaryentry{time.cal.mwd.nonmembers@ {\memgloterm{time.cal.mwd.nonmembers}}{\memglodesc{(\ref {time.cal.mwd.nonmembers})}} {\memgloref{}}|memjustarg}{1530} -\glossaryentry{time.cal.mwdlast@ {\memgloterm{time.cal.mwdlast}}{\memglodesc{(\ref {time.cal.mwdlast})}} {\memgloref{}}|memjustarg}{1530} -\glossaryentry{time.cal.mwdlast.overview@ {\memgloterm{time.cal.mwdlast.overview}}{\memglodesc{(\ref {time.cal.mwdlast.overview})}} {\memgloref{}}|memjustarg}{1530} -\glossaryentry{time.cal.mwdlast.members@ {\memgloterm{time.cal.mwdlast.members}}{\memglodesc{(\ref {time.cal.mwdlast.members})}} {\memgloref{}}|memjustarg}{1530} -\glossaryentry{time.cal.mwdlast.nonmembers@ {\memgloterm{time.cal.mwdlast.nonmembers}}{\memglodesc{(\ref {time.cal.mwdlast.nonmembers})}} {\memgloref{}}|memjustarg}{1530} -\glossaryentry{time.cal.ym@ {\memgloterm{time.cal.ym}}{\memglodesc{(\ref {time.cal.ym})}} {\memgloref{}}|memjustarg}{1531} -\glossaryentry{time.cal.ym.overview@ {\memgloterm{time.cal.ym.overview}}{\memglodesc{(\ref {time.cal.ym.overview})}} {\memgloref{}}|memjustarg}{1531} -\glossaryentry{time.cal.ym.members@ {\memgloterm{time.cal.ym.members}}{\memglodesc{(\ref {time.cal.ym.members})}} {\memgloref{}}|memjustarg}{1531} -\glossaryentry{time.cal.ym.nonmembers@ {\memgloterm{time.cal.ym.nonmembers}}{\memglodesc{(\ref {time.cal.ym.nonmembers})}} {\memgloref{}}|memjustarg}{1532} -\glossaryentry{time.cal.ymd@ {\memgloterm{time.cal.ymd}}{\memglodesc{(\ref {time.cal.ymd})}} {\memgloref{}}|memjustarg}{1533} -\glossaryentry{time.cal.ymd.overview@ {\memgloterm{time.cal.ymd.overview}}{\memglodesc{(\ref {time.cal.ymd.overview})}} {\memgloref{}}|memjustarg}{1533} -\glossaryentry{time.cal.ymd.members@ {\memgloterm{time.cal.ymd.members}}{\memglodesc{(\ref {time.cal.ymd.members})}} {\memgloref{}}|memjustarg}{1533} -\glossaryentry{time.cal.ymd.nonmembers@ {\memgloterm{time.cal.ymd.nonmembers}}{\memglodesc{(\ref {time.cal.ymd.nonmembers})}} {\memgloref{}}|memjustarg}{1535} -\glossaryentry{time.cal.ymdlast@ {\memgloterm{time.cal.ymdlast}}{\memglodesc{(\ref {time.cal.ymdlast})}} {\memgloref{}}|memjustarg}{1536} -\glossaryentry{time.cal.ymdlast.overview@ {\memgloterm{time.cal.ymdlast.overview}}{\memglodesc{(\ref {time.cal.ymdlast.overview})}} {\memgloref{}}|memjustarg}{1536} -\glossaryentry{time.cal.ymdlast.members@ {\memgloterm{time.cal.ymdlast.members}}{\memglodesc{(\ref {time.cal.ymdlast.members})}} {\memgloref{}}|memjustarg}{1536} -\glossaryentry{time.cal.ymdlast.nonmembers@ {\memgloterm{time.cal.ymdlast.nonmembers}}{\memglodesc{(\ref {time.cal.ymdlast.nonmembers})}} {\memgloref{}}|memjustarg}{1537} -\glossaryentry{time.cal.ymwd@ {\memgloterm{time.cal.ymwd}}{\memglodesc{(\ref {time.cal.ymwd})}} {\memgloref{}}|memjustarg}{1538} -\glossaryentry{time.cal.ymwd.overview@ {\memgloterm{time.cal.ymwd.overview}}{\memglodesc{(\ref {time.cal.ymwd.overview})}} {\memgloref{}}|memjustarg}{1538} -\glossaryentry{time.cal.ymwd.members@ {\memgloterm{time.cal.ymwd.members}}{\memglodesc{(\ref {time.cal.ymwd.members})}} {\memgloref{}}|memjustarg}{1539} -\glossaryentry{time.cal.ymwd.nonmembers@ {\memgloterm{time.cal.ymwd.nonmembers}}{\memglodesc{(\ref {time.cal.ymwd.nonmembers})}} {\memgloref{}}|memjustarg}{1540} -\glossaryentry{time.cal.ymwdlast@ {\memgloterm{time.cal.ymwdlast}}{\memglodesc{(\ref {time.cal.ymwdlast})}} {\memgloref{}}|memjustarg}{1540} -\glossaryentry{time.cal.ymwdlast.overview@ {\memgloterm{time.cal.ymwdlast.overview}}{\memglodesc{(\ref {time.cal.ymwdlast.overview})}} {\memgloref{}}|memjustarg}{1540} -\glossaryentry{time.cal.ymwdlast.members@ {\memgloterm{time.cal.ymwdlast.members}}{\memglodesc{(\ref {time.cal.ymwdlast.members})}} {\memgloref{}}|memjustarg}{1541} -\glossaryentry{time.cal.ymwdlast.nonmembers@ {\memgloterm{time.cal.ymwdlast.nonmembers}}{\memglodesc{(\ref {time.cal.ymwdlast.nonmembers})}} {\memgloref{}}|memjustarg}{1542} -\glossaryentry{time.cal.operators@ {\memgloterm{time.cal.operators}}{\memglodesc{(\ref {time.cal.operators})}} {\memgloref{}}|memjustarg}{1543} -\glossaryentry{time.hms@ {\memgloterm{time.hms}}{\memglodesc{(\ref {time.hms})}} {\memgloref{}}|memjustarg}{1546} -\glossaryentry{time.hms.overview@ {\memgloterm{time.hms.overview}}{\memglodesc{(\ref {time.hms.overview})}} {\memgloref{}}|memjustarg}{1546} -\glossaryentry{time.hms.members@ {\memgloterm{time.hms.members}}{\memglodesc{(\ref {time.hms.members})}} {\memgloref{}}|memjustarg}{1546} -\glossaryentry{time.hms.nonmembers@ {\memgloterm{time.hms.nonmembers}}{\memglodesc{(\ref {time.hms.nonmembers})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.12@ {\memgloterm{time.12}}{\memglodesc{(\ref {time.12})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.zone@ {\memgloterm{time.zone}}{\memglodesc{(\ref {time.zone})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.zone.general@ {\memgloterm{time.zone.general}}{\memglodesc{(\ref {time.zone.general})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.zone.db@ {\memgloterm{time.zone.db}}{\memglodesc{(\ref {time.zone.db})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.zone.db.tzdb@ {\memgloterm{time.zone.db.tzdb}}{\memglodesc{(\ref {time.zone.db.tzdb})}} {\memgloref{}}|memjustarg}{1548} -\glossaryentry{time.zone.db.list@ {\memgloterm{time.zone.db.list}}{\memglodesc{(\ref {time.zone.db.list})}} {\memgloref{}}|memjustarg}{1549} -\glossaryentry{time.zone.db.access@ {\memgloterm{time.zone.db.access}}{\memglodesc{(\ref {time.zone.db.access})}} {\memgloref{}}|memjustarg}{1550} -\glossaryentry{time.zone.db.remote@ {\memgloterm{time.zone.db.remote}}{\memglodesc{(\ref {time.zone.db.remote})}} {\memgloref{}}|memjustarg}{1550} -\glossaryentry{time.zone.exception@ {\memgloterm{time.zone.exception}}{\memglodesc{(\ref {time.zone.exception})}} {\memgloref{}}|memjustarg}{1551} -\glossaryentry{time.zone.exception.nonexist@ {\memgloterm{time.zone.exception.nonexist}}{\memglodesc{(\ref {time.zone.exception.nonexist})}} {\memgloref{}}|memjustarg}{1551} -\glossaryentry{time.zone.exception.ambig@ {\memgloterm{time.zone.exception.ambig}}{\memglodesc{(\ref {time.zone.exception.ambig})}} {\memgloref{}}|memjustarg}{1551} -\glossaryentry{time.zone.info@ {\memgloterm{time.zone.info}}{\memglodesc{(\ref {time.zone.info})}} {\memgloref{}}|memjustarg}{1552} -\glossaryentry{time.zone.info.sys@ {\memgloterm{time.zone.info.sys}}{\memglodesc{(\ref {time.zone.info.sys})}} {\memgloref{}}|memjustarg}{1552} -\glossaryentry{time.zone.info.local@ {\memgloterm{time.zone.info.local}}{\memglodesc{(\ref {time.zone.info.local})}} {\memgloref{}}|memjustarg}{1553} -\glossaryentry{time.zone.timezone@ {\memgloterm{time.zone.timezone}}{\memglodesc{(\ref {time.zone.timezone})}} {\memgloref{}}|memjustarg}{1553} -\glossaryentry{time.zone.overview@ {\memgloterm{time.zone.overview}}{\memglodesc{(\ref {time.zone.overview})}} {\memgloref{}}|memjustarg}{1553} -\glossaryentry{time.zone.members@ {\memgloterm{time.zone.members}}{\memglodesc{(\ref {time.zone.members})}} {\memgloref{}}|memjustarg}{1554} -\glossaryentry{time.zone.nonmembers@ {\memgloterm{time.zone.nonmembers}}{\memglodesc{(\ref {time.zone.nonmembers})}} {\memgloref{}}|memjustarg}{1555} -\glossaryentry{time.zone.zonedtraits@ {\memgloterm{time.zone.zonedtraits}}{\memglodesc{(\ref {time.zone.zonedtraits})}} {\memgloref{}}|memjustarg}{1555} -\glossaryentry{time.zone.zonedtime@ {\memgloterm{time.zone.zonedtime}}{\memglodesc{(\ref {time.zone.zonedtime})}} {\memgloref{}}|memjustarg}{1555} -\glossaryentry{time.zone.zonedtime.overview@ {\memgloterm{time.zone.zonedtime.overview}}{\memglodesc{(\ref {time.zone.zonedtime.overview})}} {\memgloref{}}|memjustarg}{1555} -\glossaryentry{time.zone.zonedtime.ctor@ {\memgloterm{time.zone.zonedtime.ctor}}{\memglodesc{(\ref {time.zone.zonedtime.ctor})}} {\memgloref{}}|memjustarg}{1557} -\glossaryentry{time.zone.zonedtime.members@ {\memgloterm{time.zone.zonedtime.members}}{\memglodesc{(\ref {time.zone.zonedtime.members})}} {\memgloref{}}|memjustarg}{1558} -\glossaryentry{time.zone.zonedtime.nonmembers@ {\memgloterm{time.zone.zonedtime.nonmembers}}{\memglodesc{(\ref {time.zone.zonedtime.nonmembers})}} {\memgloref{}}|memjustarg}{1559} -\glossaryentry{time.zone.leap@ {\memgloterm{time.zone.leap}}{\memglodesc{(\ref {time.zone.leap})}} {\memgloref{}}|memjustarg}{1559} -\glossaryentry{time.zone.leap.overview@ {\memgloterm{time.zone.leap.overview}}{\memglodesc{(\ref {time.zone.leap.overview})}} {\memgloref{}}|memjustarg}{1559} -\glossaryentry{time.zone.leap.members@ {\memgloterm{time.zone.leap.members}}{\memglodesc{(\ref {time.zone.leap.members})}} {\memgloref{}}|memjustarg}{1560} -\glossaryentry{time.zone.leap.nonmembers@ {\memgloterm{time.zone.leap.nonmembers}}{\memglodesc{(\ref {time.zone.leap.nonmembers})}} {\memgloref{}}|memjustarg}{1560} -\glossaryentry{time.zone.link@ {\memgloterm{time.zone.link}}{\memglodesc{(\ref {time.zone.link})}} {\memgloref{}}|memjustarg}{1561} -\glossaryentry{time.zone.link.overview@ {\memgloterm{time.zone.link.overview}}{\memglodesc{(\ref {time.zone.link.overview})}} {\memgloref{}}|memjustarg}{1561} -\glossaryentry{time.zone.link.members@ {\memgloterm{time.zone.link.members}}{\memglodesc{(\ref {time.zone.link.members})}} {\memgloref{}}|memjustarg}{1561} -\glossaryentry{time.zone.link.nonmembers@ {\memgloterm{time.zone.link.nonmembers}}{\memglodesc{(\ref {time.zone.link.nonmembers})}} {\memgloref{}}|memjustarg}{1561} -\glossaryentry{time.format@ {\memgloterm{time.format}}{\memglodesc{(\ref {time.format})}} {\memgloref{}}|memjustarg}{1561} -\glossaryentry{time.parse@ {\memgloterm{time.parse}}{\memglodesc{(\ref {time.parse})}} {\memgloref{}}|memjustarg}{1565} -\glossaryentry{ctime.syn@ {\memgloterm{ctime.syn}}{\memglodesc{(\ref {ctime.syn})}} {\memgloref{}}|memjustarg}{1569} -\glossaryentry{localization@ {\memgloterm{localization}}{\memglodesc{(\ref {localization})}} {\memgloref{}}|memjustarg}{1571} -\glossaryentry{localization.general@ {\memgloterm{localization.general}}{\memglodesc{(\ref {localization.general})}} {\memgloref{}}|memjustarg}{1571} -\glossaryentry{locale.syn@ {\memgloterm{locale.syn}}{\memglodesc{(\ref {locale.syn})}} {\memgloref{}}|memjustarg}{1571} -\glossaryentry{locales@ {\memgloterm{locales}}{\memglodesc{(\ref {locales})}} {\memgloref{}}|memjustarg}{1572} -\glossaryentry{locale@ {\memgloterm{locale}}{\memglodesc{(\ref {locale})}} {\memgloref{}}|memjustarg}{1572} -\glossaryentry{locale.general@ {\memgloterm{locale.general}}{\memglodesc{(\ref {locale.general})}} {\memgloref{}}|memjustarg}{1572} -\glossaryentry{locale.types@ {\memgloterm{locale.types}}{\memglodesc{(\ref {locale.types})}} {\memgloref{}}|memjustarg}{1574} -\glossaryentry{locale.category@ {\memgloterm{locale.category}}{\memglodesc{(\ref {locale.category})}} {\memgloref{}}|memjustarg}{1574} -\glossaryentry{locale.facet@ {\memgloterm{locale.facet}}{\memglodesc{(\ref {locale.facet})}} {\memgloref{}}|memjustarg}{1575} -\glossaryentry{locale.id@ {\memgloterm{locale.id}}{\memglodesc{(\ref {locale.id})}} {\memgloref{}}|memjustarg}{1576} -\glossaryentry{locale.cons@ {\memgloterm{locale.cons}}{\memglodesc{(\ref {locale.cons})}} {\memgloref{}}|memjustarg}{1576} -\glossaryentry{locale.members@ {\memgloterm{locale.members}}{\memglodesc{(\ref {locale.members})}} {\memgloref{}}|memjustarg}{1577} -\glossaryentry{locale.operators@ {\memgloterm{locale.operators}}{\memglodesc{(\ref {locale.operators})}} {\memgloref{}}|memjustarg}{1577} -\glossaryentry{locale.statics@ {\memgloterm{locale.statics}}{\memglodesc{(\ref {locale.statics})}} {\memgloref{}}|memjustarg}{1577} -\glossaryentry{locale.global.templates@ {\memgloterm{locale.global.templates}}{\memglodesc{(\ref {locale.global.templates})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{locale.convenience@ {\memgloterm{locale.convenience}}{\memglodesc{(\ref {locale.convenience})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{classification@ {\memgloterm{classification}}{\memglodesc{(\ref {classification})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{conversions.character@ {\memgloterm{conversions.character}}{\memglodesc{(\ref {conversions.character})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{locale.categories@ {\memgloterm{locale.categories}}{\memglodesc{(\ref {locale.categories})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{locale.categories.general@ {\memgloterm{locale.categories.general}}{\memglodesc{(\ref {locale.categories.general})}} {\memgloref{}}|memjustarg}{1578} -\glossaryentry{category.ctype@ {\memgloterm{category.ctype}}{\memglodesc{(\ref {category.ctype})}} {\memgloref{}}|memjustarg}{1579} -\glossaryentry{category.ctype.general@ {\memgloterm{category.ctype.general}}{\memglodesc{(\ref {category.ctype.general})}} {\memgloref{}}|memjustarg}{1579} -\glossaryentry{locale.ctype@ {\memgloterm{locale.ctype}}{\memglodesc{(\ref {locale.ctype})}} {\memgloref{}}|memjustarg}{1579} -\glossaryentry{locale.ctype.general@ {\memgloterm{locale.ctype.general}}{\memglodesc{(\ref {locale.ctype.general})}} {\memgloref{}}|memjustarg}{1579} -\glossaryentry{locale.ctype.members@ {\memgloterm{locale.ctype.members}}{\memglodesc{(\ref {locale.ctype.members})}} {\memgloref{}}|memjustarg}{1580} -\glossaryentry{locale.ctype.virtuals@ {\memgloterm{locale.ctype.virtuals}}{\memglodesc{(\ref {locale.ctype.virtuals})}} {\memgloref{}}|memjustarg}{1580} -\glossaryentry{locale.ctype.byname@ {\memgloterm{locale.ctype.byname}}{\memglodesc{(\ref {locale.ctype.byname})}} {\memgloref{}}|memjustarg}{1581} -\glossaryentry{facet.ctype.special@ {\memgloterm{facet.ctype.special}}{\memglodesc{(\ref {facet.ctype.special})}} {\memgloref{}}|memjustarg}{1582} -\glossaryentry{facet.ctype.special.general@ {\memgloterm{facet.ctype.special.general}}{\memglodesc{(\ref {facet.ctype.special.general})}} {\memgloref{}}|memjustarg}{1582} -\glossaryentry{facet.ctype.char.dtor@ {\memgloterm{facet.ctype.char.dtor}}{\memglodesc{(\ref {facet.ctype.char.dtor})}} {\memgloref{}}|memjustarg}{1582} -\glossaryentry{facet.ctype.char.members@ {\memgloterm{facet.ctype.char.members}}{\memglodesc{(\ref {facet.ctype.char.members})}} {\memgloref{}}|memjustarg}{1583} -\glossaryentry{facet.ctype.char.statics@ {\memgloterm{facet.ctype.char.statics}}{\memglodesc{(\ref {facet.ctype.char.statics})}} {\memgloref{}}|memjustarg}{1583} -\glossaryentry{facet.ctype.char.virtuals@ {\memgloterm{facet.ctype.char.virtuals}}{\memglodesc{(\ref {facet.ctype.char.virtuals})}} {\memgloref{}}|memjustarg}{1583} -\glossaryentry{locale.codecvt@ {\memgloterm{locale.codecvt}}{\memglodesc{(\ref {locale.codecvt})}} {\memgloref{}}|memjustarg}{1584} -\glossaryentry{locale.codecvt.general@ {\memgloterm{locale.codecvt.general}}{\memglodesc{(\ref {locale.codecvt.general})}} {\memgloref{}}|memjustarg}{1584} -\glossaryentry{locale.codecvt.members@ {\memgloterm{locale.codecvt.members}}{\memglodesc{(\ref {locale.codecvt.members})}} {\memgloref{}}|memjustarg}{1585} -\glossaryentry{locale.codecvt.virtuals@ {\memgloterm{locale.codecvt.virtuals}}{\memglodesc{(\ref {locale.codecvt.virtuals})}} {\memgloref{}}|memjustarg}{1585} -\glossaryentry{locale.codecvt.byname@ {\memgloterm{locale.codecvt.byname}}{\memglodesc{(\ref {locale.codecvt.byname})}} {\memgloref{}}|memjustarg}{1587} -\glossaryentry{category.numeric@ {\memgloterm{category.numeric}}{\memglodesc{(\ref {category.numeric})}} {\memgloref{}}|memjustarg}{1587} -\glossaryentry{category.numeric.general@ {\memgloterm{category.numeric.general}}{\memglodesc{(\ref {category.numeric.general})}} {\memgloref{}}|memjustarg}{1587} -\glossaryentry{locale.num.get@ {\memgloterm{locale.num.get}}{\memglodesc{(\ref {locale.num.get})}} {\memgloref{}}|memjustarg}{1588} -\glossaryentry{locale.num.get.general@ {\memgloterm{locale.num.get.general}}{\memglodesc{(\ref {locale.num.get.general})}} {\memgloref{}}|memjustarg}{1588} -\glossaryentry{facet.num.get.members@ {\memgloterm{facet.num.get.members}}{\memglodesc{(\ref {facet.num.get.members})}} {\memgloref{}}|memjustarg}{1589} -\glossaryentry{facet.num.get.virtuals@ {\memgloterm{facet.num.get.virtuals}}{\memglodesc{(\ref {facet.num.get.virtuals})}} {\memgloref{}}|memjustarg}{1589} -\glossaryentry{locale.nm.put@ {\memgloterm{locale.nm.put}}{\memglodesc{(\ref {locale.nm.put})}} {\memgloref{}}|memjustarg}{1592} -\glossaryentry{locale.nm.put.general@ {\memgloterm{locale.nm.put.general}}{\memglodesc{(\ref {locale.nm.put.general})}} {\memgloref{}}|memjustarg}{1592} -\glossaryentry{facet.num.put.members@ {\memgloterm{facet.num.put.members}}{\memglodesc{(\ref {facet.num.put.members})}} {\memgloref{}}|memjustarg}{1592} -\glossaryentry{facet.num.put.virtuals@ {\memgloterm{facet.num.put.virtuals}}{\memglodesc{(\ref {facet.num.put.virtuals})}} {\memgloref{}}|memjustarg}{1592} -\glossaryentry{facet.numpunct@ {\memgloterm{facet.numpunct}}{\memglodesc{(\ref {facet.numpunct})}} {\memgloref{}}|memjustarg}{1595} -\glossaryentry{locale.numpunct@ {\memgloterm{locale.numpunct}}{\memglodesc{(\ref {locale.numpunct})}} {\memgloref{}}|memjustarg}{1595} -\glossaryentry{locale.numpunct.general@ {\memgloterm{locale.numpunct.general}}{\memglodesc{(\ref {locale.numpunct.general})}} {\memgloref{}}|memjustarg}{1595} -\glossaryentry{facet.numpunct.members@ {\memgloterm{facet.numpunct.members}}{\memglodesc{(\ref {facet.numpunct.members})}} {\memgloref{}}|memjustarg}{1596} -\glossaryentry{facet.numpunct.virtuals@ {\memgloterm{facet.numpunct.virtuals}}{\memglodesc{(\ref {facet.numpunct.virtuals})}} {\memgloref{}}|memjustarg}{1596} -\glossaryentry{locale.numpunct.byname@ {\memgloterm{locale.numpunct.byname}}{\memglodesc{(\ref {locale.numpunct.byname})}} {\memgloref{}}|memjustarg}{1596} -\glossaryentry{category.collate@ {\memgloterm{category.collate}}{\memglodesc{(\ref {category.collate})}} {\memgloref{}}|memjustarg}{1597} -\glossaryentry{locale.collate@ {\memgloterm{locale.collate}}{\memglodesc{(\ref {locale.collate})}} {\memgloref{}}|memjustarg}{1597} -\glossaryentry{locale.collate.general@ {\memgloterm{locale.collate.general}}{\memglodesc{(\ref {locale.collate.general})}} {\memgloref{}}|memjustarg}{1597} -\glossaryentry{locale.collate.members@ {\memgloterm{locale.collate.members}}{\memglodesc{(\ref {locale.collate.members})}} {\memgloref{}}|memjustarg}{1597} -\glossaryentry{locale.collate.virtuals@ {\memgloterm{locale.collate.virtuals}}{\memglodesc{(\ref {locale.collate.virtuals})}} {\memgloref{}}|memjustarg}{1597} -\glossaryentry{locale.collate.byname@ {\memgloterm{locale.collate.byname}}{\memglodesc{(\ref {locale.collate.byname})}} {\memgloref{}}|memjustarg}{1598} -\glossaryentry{category.time@ {\memgloterm{category.time}}{\memglodesc{(\ref {category.time})}} {\memgloref{}}|memjustarg}{1598} -\glossaryentry{category.time.general@ {\memgloterm{category.time.general}}{\memglodesc{(\ref {category.time.general})}} {\memgloref{}}|memjustarg}{1598} -\glossaryentry{locale.time.get@ {\memgloterm{locale.time.get}}{\memglodesc{(\ref {locale.time.get})}} {\memgloref{}}|memjustarg}{1598} -\glossaryentry{locale.time.get.general@ {\memgloterm{locale.time.get.general}}{\memglodesc{(\ref {locale.time.get.general})}} {\memgloref{}}|memjustarg}{1598} -\glossaryentry{locale.time.get.members@ {\memgloterm{locale.time.get.members}}{\memglodesc{(\ref {locale.time.get.members})}} {\memgloref{}}|memjustarg}{1599} -\glossaryentry{locale.time.get.virtuals@ {\memgloterm{locale.time.get.virtuals}}{\memglodesc{(\ref {locale.time.get.virtuals})}} {\memgloref{}}|memjustarg}{1600} -\glossaryentry{locale.time.get.byname@ {\memgloterm{locale.time.get.byname}}{\memglodesc{(\ref {locale.time.get.byname})}} {\memgloref{}}|memjustarg}{1601} -\glossaryentry{locale.time.put@ {\memgloterm{locale.time.put}}{\memglodesc{(\ref {locale.time.put})}} {\memgloref{}}|memjustarg}{1602} -\glossaryentry{locale.time.put.members@ {\memgloterm{locale.time.put.members}}{\memglodesc{(\ref {locale.time.put.members})}} {\memgloref{}}|memjustarg}{1602} -\glossaryentry{locale.time.put.virtuals@ {\memgloterm{locale.time.put.virtuals}}{\memglodesc{(\ref {locale.time.put.virtuals})}} {\memgloref{}}|memjustarg}{1603} -\glossaryentry{locale.time.put.byname@ {\memgloterm{locale.time.put.byname}}{\memglodesc{(\ref {locale.time.put.byname})}} {\memgloref{}}|memjustarg}{1603} -\glossaryentry{category.monetary@ {\memgloterm{category.monetary}}{\memglodesc{(\ref {category.monetary})}} {\memgloref{}}|memjustarg}{1603} -\glossaryentry{category.monetary.general@ {\memgloterm{category.monetary.general}}{\memglodesc{(\ref {category.monetary.general})}} {\memgloref{}}|memjustarg}{1603} -\glossaryentry{locale.money.get@ {\memgloterm{locale.money.get}}{\memglodesc{(\ref {locale.money.get})}} {\memgloref{}}|memjustarg}{1603} -\glossaryentry{locale.money.get.members@ {\memgloterm{locale.money.get.members}}{\memglodesc{(\ref {locale.money.get.members})}} {\memgloref{}}|memjustarg}{1604} -\glossaryentry{locale.money.get.virtuals@ {\memgloterm{locale.money.get.virtuals}}{\memglodesc{(\ref {locale.money.get.virtuals})}} {\memgloref{}}|memjustarg}{1604} -\glossaryentry{locale.money.put@ {\memgloterm{locale.money.put}}{\memglodesc{(\ref {locale.money.put})}} {\memgloref{}}|memjustarg}{1605} -\glossaryentry{locale.money.put.members@ {\memgloterm{locale.money.put.members}}{\memglodesc{(\ref {locale.money.put.members})}} {\memgloref{}}|memjustarg}{1605} -\glossaryentry{locale.money.put.virtuals@ {\memgloterm{locale.money.put.virtuals}}{\memglodesc{(\ref {locale.money.put.virtuals})}} {\memgloref{}}|memjustarg}{1605} -\glossaryentry{locale.moneypunct@ {\memgloterm{locale.moneypunct}}{\memglodesc{(\ref {locale.moneypunct})}} {\memgloref{}}|memjustarg}{1606} -\glossaryentry{locale.moneypunct.general@ {\memgloterm{locale.moneypunct.general}}{\memglodesc{(\ref {locale.moneypunct.general})}} {\memgloref{}}|memjustarg}{1606} -\glossaryentry{locale.moneypunct.members@ {\memgloterm{locale.moneypunct.members}}{\memglodesc{(\ref {locale.moneypunct.members})}} {\memgloref{}}|memjustarg}{1607} -\glossaryentry{locale.moneypunct.virtuals@ {\memgloterm{locale.moneypunct.virtuals}}{\memglodesc{(\ref {locale.moneypunct.virtuals})}} {\memgloref{}}|memjustarg}{1607} -\glossaryentry{locale.moneypunct.byname@ {\memgloterm{locale.moneypunct.byname}}{\memglodesc{(\ref {locale.moneypunct.byname})}} {\memgloref{}}|memjustarg}{1608} -\glossaryentry{category.messages@ {\memgloterm{category.messages}}{\memglodesc{(\ref {category.messages})}} {\memgloref{}}|memjustarg}{1608} -\glossaryentry{category.messages.general@ {\memgloterm{category.messages.general}}{\memglodesc{(\ref {category.messages.general})}} {\memgloref{}}|memjustarg}{1608} -\glossaryentry{locale.messages@ {\memgloterm{locale.messages}}{\memglodesc{(\ref {locale.messages})}} {\memgloref{}}|memjustarg}{1609} -\glossaryentry{locale.messages.general@ {\memgloterm{locale.messages.general}}{\memglodesc{(\ref {locale.messages.general})}} {\memgloref{}}|memjustarg}{1609} -\glossaryentry{locale.messages.members@ {\memgloterm{locale.messages.members}}{\memglodesc{(\ref {locale.messages.members})}} {\memgloref{}}|memjustarg}{1609} -\glossaryentry{locale.messages.virtuals@ {\memgloterm{locale.messages.virtuals}}{\memglodesc{(\ref {locale.messages.virtuals})}} {\memgloref{}}|memjustarg}{1609} -\glossaryentry{locale.messages.byname@ {\memgloterm{locale.messages.byname}}{\memglodesc{(\ref {locale.messages.byname})}} {\memgloref{}}|memjustarg}{1610} -\glossaryentry{c.locales@ {\memgloterm{c.locales}}{\memglodesc{(\ref {c.locales})}} {\memgloref{}}|memjustarg}{1610} -\glossaryentry{clocale.syn@ {\memgloterm{clocale.syn}}{\memglodesc{(\ref {clocale.syn})}} {\memgloref{}}|memjustarg}{1610} -\glossaryentry{clocale.data.races@ {\memgloterm{clocale.data.races}}{\memglodesc{(\ref {clocale.data.races})}} {\memgloref{}}|memjustarg}{1610} -\glossaryentry{input.output@ {\memgloterm{input.output}}{\memglodesc{(\ref {input.output})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{input.output.general@ {\memgloterm{input.output.general}}{\memglodesc{(\ref {input.output.general})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{iostreams.requirements@ {\memgloterm{iostreams.requirements}}{\memglodesc{(\ref {iostreams.requirements})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{iostream.limits.imbue@ {\memgloterm{iostream.limits.imbue}}{\memglodesc{(\ref {iostream.limits.imbue})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{stream.types@ {\memgloterm{stream.types}}{\memglodesc{(\ref {stream.types})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{iostreams.limits.pos@ {\memgloterm{iostreams.limits.pos}}{\memglodesc{(\ref {iostreams.limits.pos})}} {\memgloref{}}|memjustarg}{1611} -\glossaryentry{iostreams.threadsafety@ {\memgloterm{iostreams.threadsafety}}{\memglodesc{(\ref {iostreams.threadsafety})}} {\memgloref{}}|memjustarg}{1612} -\glossaryentry{iostream.forward@ {\memgloterm{iostream.forward}}{\memglodesc{(\ref {iostream.forward})}} {\memgloref{}}|memjustarg}{1612} -\glossaryentry{iosfwd.syn@ {\memgloterm{iosfwd.syn}}{\memglodesc{(\ref {iosfwd.syn})}} {\memgloref{}}|memjustarg}{1612} -\glossaryentry{iostream.forward.overview@ {\memgloterm{iostream.forward.overview}}{\memglodesc{(\ref {iostream.forward.overview})}} {\memgloref{}}|memjustarg}{1614} -\glossaryentry{iostream.objects@ {\memgloterm{iostream.objects}}{\memglodesc{(\ref {iostream.objects})}} {\memgloref{}}|memjustarg}{1614} -\glossaryentry{iostream.syn@ {\memgloterm{iostream.syn}}{\memglodesc{(\ref {iostream.syn})}} {\memgloref{}}|memjustarg}{1614} -\glossaryentry{iostream.objects.overview@ {\memgloterm{iostream.objects.overview}}{\memglodesc{(\ref {iostream.objects.overview})}} {\memgloref{}}|memjustarg}{1614} -\glossaryentry{narrow.stream.objects@ {\memgloterm{narrow.stream.objects}}{\memglodesc{(\ref {narrow.stream.objects})}} {\memgloref{}}|memjustarg}{1615} -\glossaryentry{wide.stream.objects@ {\memgloterm{wide.stream.objects}}{\memglodesc{(\ref {wide.stream.objects})}} {\memgloref{}}|memjustarg}{1615} -\glossaryentry{iostreams.base@ {\memgloterm{iostreams.base}}{\memglodesc{(\ref {iostreams.base})}} {\memgloref{}}|memjustarg}{1616} -\glossaryentry{ios.syn@ {\memgloterm{ios.syn}}{\memglodesc{(\ref {ios.syn})}} {\memgloref{}}|memjustarg}{1616} -\glossaryentry{ios.base@ {\memgloterm{ios.base}}{\memglodesc{(\ref {ios.base})}} {\memgloref{}}|memjustarg}{1617} -\glossaryentry{ios.base.general@ {\memgloterm{ios.base.general}}{\memglodesc{(\ref {ios.base.general})}} {\memgloref{}}|memjustarg}{1617} -\glossaryentry{ios.types@ {\memgloterm{ios.types}}{\memglodesc{(\ref {ios.types})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.failure@ {\memgloterm{ios.failure}}{\memglodesc{(\ref {ios.failure})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.fmtflags@ {\memgloterm{ios.fmtflags}}{\memglodesc{(\ref {ios.fmtflags})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.iostate@ {\memgloterm{ios.iostate}}{\memglodesc{(\ref {ios.iostate})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.openmode@ {\memgloterm{ios.openmode}}{\memglodesc{(\ref {ios.openmode})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.seekdir@ {\memgloterm{ios.seekdir}}{\memglodesc{(\ref {ios.seekdir})}} {\memgloref{}}|memjustarg}{1619} -\glossaryentry{ios.init@ {\memgloterm{ios.init}}{\memglodesc{(\ref {ios.init})}} {\memgloref{}}|memjustarg}{1621} -\glossaryentry{fmtflags.state@ {\memgloterm{fmtflags.state}}{\memglodesc{(\ref {fmtflags.state})}} {\memgloref{}}|memjustarg}{1621} -\glossaryentry{ios.base.locales@ {\memgloterm{ios.base.locales}}{\memglodesc{(\ref {ios.base.locales})}} {\memgloref{}}|memjustarg}{1622} -\glossaryentry{ios.members.static@ {\memgloterm{ios.members.static}}{\memglodesc{(\ref {ios.members.static})}} {\memgloref{}}|memjustarg}{1622} -\glossaryentry{ios.base.storage@ {\memgloterm{ios.base.storage}}{\memglodesc{(\ref {ios.base.storage})}} {\memgloref{}}|memjustarg}{1622} -\glossaryentry{ios.base.callback@ {\memgloterm{ios.base.callback}}{\memglodesc{(\ref {ios.base.callback})}} {\memgloref{}}|memjustarg}{1623} -\glossaryentry{ios.base.cons@ {\memgloterm{ios.base.cons}}{\memglodesc{(\ref {ios.base.cons})}} {\memgloref{}}|memjustarg}{1623} -\glossaryentry{fpos@ {\memgloterm{fpos}}{\memglodesc{(\ref {fpos})}} {\memgloref{}}|memjustarg}{1623} -\glossaryentry{fpos.members@ {\memgloterm{fpos.members}}{\memglodesc{(\ref {fpos.members})}} {\memgloref{}}|memjustarg}{1624} -\glossaryentry{fpos.operations@ {\memgloterm{fpos.operations}}{\memglodesc{(\ref {fpos.operations})}} {\memgloref{}}|memjustarg}{1624} -\glossaryentry{ios@ {\memgloterm{ios}}{\memglodesc{(\ref {ios})}} {\memgloref{}}|memjustarg}{1625} -\glossaryentry{ios.overview@ {\memgloterm{ios.overview}}{\memglodesc{(\ref {ios.overview})}} {\memgloref{}}|memjustarg}{1625} -\glossaryentry{basic.ios.cons@ {\memgloterm{basic.ios.cons}}{\memglodesc{(\ref {basic.ios.cons})}} {\memgloref{}}|memjustarg}{1626} -\glossaryentry{basic.ios.members@ {\memgloterm{basic.ios.members}}{\memglodesc{(\ref {basic.ios.members})}} {\memgloref{}}|memjustarg}{1626} -\glossaryentry{iostate.flags@ {\memgloterm{iostate.flags}}{\memglodesc{(\ref {iostate.flags})}} {\memgloref{}}|memjustarg}{1628} -\glossaryentry{std.ios.manip@ {\memgloterm{std.ios.manip}}{\memglodesc{(\ref {std.ios.manip})}} {\memgloref{}}|memjustarg}{1629} -\glossaryentry{fmtflags.manip@ {\memgloterm{fmtflags.manip}}{\memglodesc{(\ref {fmtflags.manip})}} {\memgloref{}}|memjustarg}{1629} -\glossaryentry{adjustfield.manip@ {\memgloterm{adjustfield.manip}}{\memglodesc{(\ref {adjustfield.manip})}} {\memgloref{}}|memjustarg}{1630} -\glossaryentry{basefield.manip@ {\memgloterm{basefield.manip}}{\memglodesc{(\ref {basefield.manip})}} {\memgloref{}}|memjustarg}{1630} -\glossaryentry{floatfield.manip@ {\memgloterm{floatfield.manip}}{\memglodesc{(\ref {floatfield.manip})}} {\memgloref{}}|memjustarg}{1630} -\glossaryentry{error.reporting@ {\memgloterm{error.reporting}}{\memglodesc{(\ref {error.reporting})}} {\memgloref{}}|memjustarg}{1631} -\glossaryentry{stream.buffers@ {\memgloterm{stream.buffers}}{\memglodesc{(\ref {stream.buffers})}} {\memgloref{}}|memjustarg}{1631} -\glossaryentry{streambuf.syn@ {\memgloterm{streambuf.syn}}{\memglodesc{(\ref {streambuf.syn})}} {\memgloref{}}|memjustarg}{1631} -\glossaryentry{streambuf.reqts@ {\memgloterm{streambuf.reqts}}{\memglodesc{(\ref {streambuf.reqts})}} {\memgloref{}}|memjustarg}{1631} -\glossaryentry{streambuf@ {\memgloterm{streambuf}}{\memglodesc{(\ref {streambuf})}} {\memgloref{}}|memjustarg}{1632} -\glossaryentry{streambuf.general@ {\memgloterm{streambuf.general}}{\memglodesc{(\ref {streambuf.general})}} {\memgloref{}}|memjustarg}{1632} -\glossaryentry{streambuf.cons@ {\memgloterm{streambuf.cons}}{\memglodesc{(\ref {streambuf.cons})}} {\memgloref{}}|memjustarg}{1633} -\glossaryentry{streambuf.members@ {\memgloterm{streambuf.members}}{\memglodesc{(\ref {streambuf.members})}} {\memgloref{}}|memjustarg}{1634} -\glossaryentry{streambuf.locales@ {\memgloterm{streambuf.locales}}{\memglodesc{(\ref {streambuf.locales})}} {\memgloref{}}|memjustarg}{1634} -\glossaryentry{streambuf.buffer@ {\memgloterm{streambuf.buffer}}{\memglodesc{(\ref {streambuf.buffer})}} {\memgloref{}}|memjustarg}{1634} -\glossaryentry{streambuf.pub.get@ {\memgloterm{streambuf.pub.get}}{\memglodesc{(\ref {streambuf.pub.get})}} {\memgloref{}}|memjustarg}{1634} -\glossaryentry{streambuf.pub.pback@ {\memgloterm{streambuf.pub.pback}}{\memglodesc{(\ref {streambuf.pub.pback})}} {\memgloref{}}|memjustarg}{1635} -\glossaryentry{streambuf.pub.put@ {\memgloterm{streambuf.pub.put}}{\memglodesc{(\ref {streambuf.pub.put})}} {\memgloref{}}|memjustarg}{1635} -\glossaryentry{streambuf.protected@ {\memgloterm{streambuf.protected}}{\memglodesc{(\ref {streambuf.protected})}} {\memgloref{}}|memjustarg}{1635} -\glossaryentry{streambuf.assign@ {\memgloterm{streambuf.assign}}{\memglodesc{(\ref {streambuf.assign})}} {\memgloref{}}|memjustarg}{1635} -\glossaryentry{streambuf.get.area@ {\memgloterm{streambuf.get.area}}{\memglodesc{(\ref {streambuf.get.area})}} {\memgloref{}}|memjustarg}{1636} -\glossaryentry{streambuf.put.area@ {\memgloterm{streambuf.put.area}}{\memglodesc{(\ref {streambuf.put.area})}} {\memgloref{}}|memjustarg}{1636} -\glossaryentry{streambuf.virtuals@ {\memgloterm{streambuf.virtuals}}{\memglodesc{(\ref {streambuf.virtuals})}} {\memgloref{}}|memjustarg}{1636} -\glossaryentry{streambuf.virt.locales@ {\memgloterm{streambuf.virt.locales}}{\memglodesc{(\ref {streambuf.virt.locales})}} {\memgloref{}}|memjustarg}{1636} -\glossaryentry{streambuf.virt.buffer@ {\memgloterm{streambuf.virt.buffer}}{\memglodesc{(\ref {streambuf.virt.buffer})}} {\memgloref{}}|memjustarg}{1636} -\glossaryentry{streambuf.virt.get@ {\memgloterm{streambuf.virt.get}}{\memglodesc{(\ref {streambuf.virt.get})}} {\memgloref{}}|memjustarg}{1637} -\glossaryentry{streambuf.virt.pback@ {\memgloterm{streambuf.virt.pback}}{\memglodesc{(\ref {streambuf.virt.pback})}} {\memgloref{}}|memjustarg}{1638} -\glossaryentry{streambuf.virt.put@ {\memgloterm{streambuf.virt.put}}{\memglodesc{(\ref {streambuf.virt.put})}} {\memgloref{}}|memjustarg}{1638} -\glossaryentry{iostream.format@ {\memgloterm{iostream.format}}{\memglodesc{(\ref {iostream.format})}} {\memgloref{}}|memjustarg}{1639} -\glossaryentry{istream.syn@ {\memgloterm{istream.syn}}{\memglodesc{(\ref {istream.syn})}} {\memgloref{}}|memjustarg}{1639} -\glossaryentry{ostream.syn@ {\memgloterm{ostream.syn}}{\memglodesc{(\ref {ostream.syn})}} {\memgloref{}}|memjustarg}{1639} -\glossaryentry{iomanip.syn@ {\memgloterm{iomanip.syn}}{\memglodesc{(\ref {iomanip.syn})}} {\memgloref{}}|memjustarg}{1640} -\glossaryentry{print.syn@ {\memgloterm{print.syn}}{\memglodesc{(\ref {print.syn})}} {\memgloref{}}|memjustarg}{1640} -\glossaryentry{input.streams@ {\memgloterm{input.streams}}{\memglodesc{(\ref {input.streams})}} {\memgloref{}}|memjustarg}{1641} -\glossaryentry{input.streams.general@ {\memgloterm{input.streams.general}}{\memglodesc{(\ref {input.streams.general})}} {\memgloref{}}|memjustarg}{1641} -\glossaryentry{istream@ {\memgloterm{istream}}{\memglodesc{(\ref {istream})}} {\memgloref{}}|memjustarg}{1641} -\glossaryentry{istream.general@ {\memgloterm{istream.general}}{\memglodesc{(\ref {istream.general})}} {\memgloref{}}|memjustarg}{1641} -\glossaryentry{istream.cons@ {\memgloterm{istream.cons}}{\memglodesc{(\ref {istream.cons})}} {\memgloref{}}|memjustarg}{1642} -\glossaryentry{istream.assign@ {\memgloterm{istream.assign}}{\memglodesc{(\ref {istream.assign})}} {\memgloref{}}|memjustarg}{1643} -\glossaryentry{istream.sentry@ {\memgloterm{istream.sentry}}{\memglodesc{(\ref {istream.sentry})}} {\memgloref{}}|memjustarg}{1643} -\glossaryentry{istream.formatted@ {\memgloterm{istream.formatted}}{\memglodesc{(\ref {istream.formatted})}} {\memgloref{}}|memjustarg}{1644} -\glossaryentry{istream.formatted.reqmts@ {\memgloterm{istream.formatted.reqmts}}{\memglodesc{(\ref {istream.formatted.reqmts})}} {\memgloref{}}|memjustarg}{1644} -\glossaryentry{istream.formatted.arithmetic@ {\memgloterm{istream.formatted.arithmetic}}{\memglodesc{(\ref {istream.formatted.arithmetic})}} {\memgloref{}}|memjustarg}{1644} -\glossaryentry{istream.extractors@ {\memgloterm{istream.extractors}}{\memglodesc{(\ref {istream.extractors})}} {\memgloref{}}|memjustarg}{1645} -\glossaryentry{istream.unformatted@ {\memgloterm{istream.unformatted}}{\memglodesc{(\ref {istream.unformatted})}} {\memgloref{}}|memjustarg}{1646} -\glossaryentry{istream.manip@ {\memgloterm{istream.manip}}{\memglodesc{(\ref {istream.manip})}} {\memgloref{}}|memjustarg}{1650} -\glossaryentry{istream.rvalue@ {\memgloterm{istream.rvalue}}{\memglodesc{(\ref {istream.rvalue})}} {\memgloref{}}|memjustarg}{1651} -\glossaryentry{iostreamclass@ {\memgloterm{iostreamclass}}{\memglodesc{(\ref {iostreamclass})}} {\memgloref{}}|memjustarg}{1651} -\glossaryentry{iostreamclass.general@ {\memgloterm{iostreamclass.general}}{\memglodesc{(\ref {iostreamclass.general})}} {\memgloref{}}|memjustarg}{1651} -\glossaryentry{iostream.cons@ {\memgloterm{iostream.cons}}{\memglodesc{(\ref {iostream.cons})}} {\memgloref{}}|memjustarg}{1651} -\glossaryentry{iostream.dest@ {\memgloterm{iostream.dest}}{\memglodesc{(\ref {iostream.dest})}} {\memgloref{}}|memjustarg}{1651} -\glossaryentry{iostream.assign@ {\memgloterm{iostream.assign}}{\memglodesc{(\ref {iostream.assign})}} {\memgloref{}}|memjustarg}{1652} -\glossaryentry{output.streams@ {\memgloterm{output.streams}}{\memglodesc{(\ref {output.streams})}} {\memgloref{}}|memjustarg}{1652} -\glossaryentry{output.streams.general@ {\memgloterm{output.streams.general}}{\memglodesc{(\ref {output.streams.general})}} {\memgloref{}}|memjustarg}{1652} -\glossaryentry{ostream@ {\memgloterm{ostream}}{\memglodesc{(\ref {ostream})}} {\memgloref{}}|memjustarg}{1652} -\glossaryentry{ostream.general@ {\memgloterm{ostream.general}}{\memglodesc{(\ref {ostream.general})}} {\memgloref{}}|memjustarg}{1652} -\glossaryentry{ostream.cons@ {\memgloterm{ostream.cons}}{\memglodesc{(\ref {ostream.cons})}} {\memgloref{}}|memjustarg}{1654} -\glossaryentry{ostream.assign@ {\memgloterm{ostream.assign}}{\memglodesc{(\ref {ostream.assign})}} {\memgloref{}}|memjustarg}{1654} -\glossaryentry{ostream.sentry@ {\memgloterm{ostream.sentry}}{\memglodesc{(\ref {ostream.sentry})}} {\memgloref{}}|memjustarg}{1654} -\glossaryentry{ostream.seeks@ {\memgloterm{ostream.seeks}}{\memglodesc{(\ref {ostream.seeks})}} {\memgloref{}}|memjustarg}{1655} -\glossaryentry{ostream.formatted@ {\memgloterm{ostream.formatted}}{\memglodesc{(\ref {ostream.formatted})}} {\memgloref{}}|memjustarg}{1655} -\glossaryentry{ostream.formatted.reqmts@ {\memgloterm{ostream.formatted.reqmts}}{\memglodesc{(\ref {ostream.formatted.reqmts})}} {\memgloref{}}|memjustarg}{1655} -\glossaryentry{ostream.inserters.arithmetic@ {\memgloterm{ostream.inserters.arithmetic}}{\memglodesc{(\ref {ostream.inserters.arithmetic})}} {\memgloref{}}|memjustarg}{1656} -\glossaryentry{ostream.inserters@ {\memgloterm{ostream.inserters}}{\memglodesc{(\ref {ostream.inserters})}} {\memgloref{}}|memjustarg}{1657} -\glossaryentry{ostream.inserters.character@ {\memgloterm{ostream.inserters.character}}{\memglodesc{(\ref {ostream.inserters.character})}} {\memgloref{}}|memjustarg}{1658} -\glossaryentry{ostream.formatted.print@ {\memgloterm{ostream.formatted.print}}{\memglodesc{(\ref {ostream.formatted.print})}} {\memgloref{}}|memjustarg}{1659} -\glossaryentry{ostream.unformatted@ {\memgloterm{ostream.unformatted}}{\memglodesc{(\ref {ostream.unformatted})}} {\memgloref{}}|memjustarg}{1659} -\glossaryentry{ostream.manip@ {\memgloterm{ostream.manip}}{\memglodesc{(\ref {ostream.manip})}} {\memgloref{}}|memjustarg}{1660} -\glossaryentry{ostream.rvalue@ {\memgloterm{ostream.rvalue}}{\memglodesc{(\ref {ostream.rvalue})}} {\memgloref{}}|memjustarg}{1660} -\glossaryentry{std.manip@ {\memgloterm{std.manip}}{\memglodesc{(\ref {std.manip})}} {\memgloref{}}|memjustarg}{1661} -\glossaryentry{ext.manip@ {\memgloterm{ext.manip}}{\memglodesc{(\ref {ext.manip})}} {\memgloref{}}|memjustarg}{1662} -\glossaryentry{quoted.manip@ {\memgloterm{quoted.manip}}{\memglodesc{(\ref {quoted.manip})}} {\memgloref{}}|memjustarg}{1664} -\glossaryentry{print.fun@ {\memgloterm{print.fun}}{\memglodesc{(\ref {print.fun})}} {\memgloref{}}|memjustarg}{1665} -\glossaryentry{string.streams@ {\memgloterm{string.streams}}{\memglodesc{(\ref {string.streams})}} {\memgloref{}}|memjustarg}{1666} -\glossaryentry{sstream.syn@ {\memgloterm{sstream.syn}}{\memglodesc{(\ref {sstream.syn})}} {\memgloref{}}|memjustarg}{1666} -\glossaryentry{stringbuf@ {\memgloterm{stringbuf}}{\memglodesc{(\ref {stringbuf})}} {\memgloref{}}|memjustarg}{1667} -\glossaryentry{stringbuf.general@ {\memgloterm{stringbuf.general}}{\memglodesc{(\ref {stringbuf.general})}} {\memgloref{}}|memjustarg}{1667} -\glossaryentry{stringbuf.cons@ {\memgloterm{stringbuf.cons}}{\memglodesc{(\ref {stringbuf.cons})}} {\memgloref{}}|memjustarg}{1668} -\glossaryentry{stringbuf.assign@ {\memgloterm{stringbuf.assign}}{\memglodesc{(\ref {stringbuf.assign})}} {\memgloref{}}|memjustarg}{1669} -\glossaryentry{stringbuf.members@ {\memgloterm{stringbuf.members}}{\memglodesc{(\ref {stringbuf.members})}} {\memgloref{}}|memjustarg}{1670} -\glossaryentry{stringbuf.virtuals@ {\memgloterm{stringbuf.virtuals}}{\memglodesc{(\ref {stringbuf.virtuals})}} {\memgloref{}}|memjustarg}{1671} -\glossaryentry{istringstream@ {\memgloterm{istringstream}}{\memglodesc{(\ref {istringstream})}} {\memgloref{}}|memjustarg}{1672} -\glossaryentry{istringstream.general@ {\memgloterm{istringstream.general}}{\memglodesc{(\ref {istringstream.general})}} {\memgloref{}}|memjustarg}{1672} -\glossaryentry{istringstream.cons@ {\memgloterm{istringstream.cons}}{\memglodesc{(\ref {istringstream.cons})}} {\memgloref{}}|memjustarg}{1674} -\glossaryentry{istringstream.swap@ {\memgloterm{istringstream.swap}}{\memglodesc{(\ref {istringstream.swap})}} {\memgloref{}}|memjustarg}{1674} -\glossaryentry{istringstream.members@ {\memgloterm{istringstream.members}}{\memglodesc{(\ref {istringstream.members})}} {\memgloref{}}|memjustarg}{1674} -\glossaryentry{ostringstream@ {\memgloterm{ostringstream}}{\memglodesc{(\ref {ostringstream})}} {\memgloref{}}|memjustarg}{1675} -\glossaryentry{ostringstream.general@ {\memgloterm{ostringstream.general}}{\memglodesc{(\ref {ostringstream.general})}} {\memgloref{}}|memjustarg}{1675} -\glossaryentry{ostringstream.cons@ {\memgloterm{ostringstream.cons}}{\memglodesc{(\ref {ostringstream.cons})}} {\memgloref{}}|memjustarg}{1676} -\glossaryentry{ostringstream.swap@ {\memgloterm{ostringstream.swap}}{\memglodesc{(\ref {ostringstream.swap})}} {\memgloref{}}|memjustarg}{1677} -\glossaryentry{ostringstream.members@ {\memgloterm{ostringstream.members}}{\memglodesc{(\ref {ostringstream.members})}} {\memgloref{}}|memjustarg}{1677} -\glossaryentry{stringstream@ {\memgloterm{stringstream}}{\memglodesc{(\ref {stringstream})}} {\memgloref{}}|memjustarg}{1677} -\glossaryentry{stringstream.general@ {\memgloterm{stringstream.general}}{\memglodesc{(\ref {stringstream.general})}} {\memgloref{}}|memjustarg}{1677} -\glossaryentry{stringstream.cons@ {\memgloterm{stringstream.cons}}{\memglodesc{(\ref {stringstream.cons})}} {\memgloref{}}|memjustarg}{1679} -\glossaryentry{stringstream.swap@ {\memgloterm{stringstream.swap}}{\memglodesc{(\ref {stringstream.swap})}} {\memgloref{}}|memjustarg}{1679} -\glossaryentry{stringstream.members@ {\memgloterm{stringstream.members}}{\memglodesc{(\ref {stringstream.members})}} {\memgloref{}}|memjustarg}{1679} -\glossaryentry{span.streams@ {\memgloterm{span.streams}}{\memglodesc{(\ref {span.streams})}} {\memgloref{}}|memjustarg}{1680} -\glossaryentry{span.streams.overview@ {\memgloterm{span.streams.overview}}{\memglodesc{(\ref {span.streams.overview})}} {\memgloref{}}|memjustarg}{1680} -\glossaryentry{spanstream.syn@ {\memgloterm{spanstream.syn}}{\memglodesc{(\ref {spanstream.syn})}} {\memgloref{}}|memjustarg}{1680} -\glossaryentry{spanbuf@ {\memgloterm{spanbuf}}{\memglodesc{(\ref {spanbuf})}} {\memgloref{}}|memjustarg}{1681} -\glossaryentry{spanbuf.general@ {\memgloterm{spanbuf.general}}{\memglodesc{(\ref {spanbuf.general})}} {\memgloref{}}|memjustarg}{1681} -\glossaryentry{spanbuf.cons@ {\memgloterm{spanbuf.cons}}{\memglodesc{(\ref {spanbuf.cons})}} {\memgloref{}}|memjustarg}{1682} -\glossaryentry{spanbuf.assign@ {\memgloterm{spanbuf.assign}}{\memglodesc{(\ref {spanbuf.assign})}} {\memgloref{}}|memjustarg}{1682} -\glossaryentry{spanbuf.members@ {\memgloterm{spanbuf.members}}{\memglodesc{(\ref {spanbuf.members})}} {\memgloref{}}|memjustarg}{1682} -\glossaryentry{spanbuf.virtuals@ {\memgloterm{spanbuf.virtuals}}{\memglodesc{(\ref {spanbuf.virtuals})}} {\memgloref{}}|memjustarg}{1683} -\glossaryentry{ispanstream@ {\memgloterm{ispanstream}}{\memglodesc{(\ref {ispanstream})}} {\memgloref{}}|memjustarg}{1683} -\glossaryentry{ispanstream.general@ {\memgloterm{ispanstream.general}}{\memglodesc{(\ref {ispanstream.general})}} {\memgloref{}}|memjustarg}{1683} -\glossaryentry{ispanstream.cons@ {\memgloterm{ispanstream.cons}}{\memglodesc{(\ref {ispanstream.cons})}} {\memgloref{}}|memjustarg}{1684} -\glossaryentry{ispanstream.swap@ {\memgloterm{ispanstream.swap}}{\memglodesc{(\ref {ispanstream.swap})}} {\memgloref{}}|memjustarg}{1684} -\glossaryentry{ispanstream.members@ {\memgloterm{ispanstream.members}}{\memglodesc{(\ref {ispanstream.members})}} {\memgloref{}}|memjustarg}{1684} -\glossaryentry{ospanstream@ {\memgloterm{ospanstream}}{\memglodesc{(\ref {ospanstream})}} {\memgloref{}}|memjustarg}{1685} -\glossaryentry{ospanstream.general@ {\memgloterm{ospanstream.general}}{\memglodesc{(\ref {ospanstream.general})}} {\memgloref{}}|memjustarg}{1685} -\glossaryentry{ospanstream.cons@ {\memgloterm{ospanstream.cons}}{\memglodesc{(\ref {ospanstream.cons})}} {\memgloref{}}|memjustarg}{1685} -\glossaryentry{ospanstream.swap@ {\memgloterm{ospanstream.swap}}{\memglodesc{(\ref {ospanstream.swap})}} {\memgloref{}}|memjustarg}{1686} -\glossaryentry{ospanstream.members@ {\memgloterm{ospanstream.members}}{\memglodesc{(\ref {ospanstream.members})}} {\memgloref{}}|memjustarg}{1686} -\glossaryentry{spanstream@ {\memgloterm{spanstream}}{\memglodesc{(\ref {spanstream})}} {\memgloref{}}|memjustarg}{1686} -\glossaryentry{spanstream.general@ {\memgloterm{spanstream.general}}{\memglodesc{(\ref {spanstream.general})}} {\memgloref{}}|memjustarg}{1686} -\glossaryentry{spanstream.cons@ {\memgloterm{spanstream.cons}}{\memglodesc{(\ref {spanstream.cons})}} {\memgloref{}}|memjustarg}{1687} -\glossaryentry{spanstream.swap@ {\memgloterm{spanstream.swap}}{\memglodesc{(\ref {spanstream.swap})}} {\memgloref{}}|memjustarg}{1687} -\glossaryentry{spanstream.members@ {\memgloterm{spanstream.members}}{\memglodesc{(\ref {spanstream.members})}} {\memgloref{}}|memjustarg}{1687} -\glossaryentry{file.streams@ {\memgloterm{file.streams}}{\memglodesc{(\ref {file.streams})}} {\memgloref{}}|memjustarg}{1687} -\glossaryentry{fstream.syn@ {\memgloterm{fstream.syn}}{\memglodesc{(\ref {fstream.syn})}} {\memgloref{}}|memjustarg}{1687} -\glossaryentry{filebuf@ {\memgloterm{filebuf}}{\memglodesc{(\ref {filebuf})}} {\memgloref{}}|memjustarg}{1688} -\glossaryentry{filebuf.general@ {\memgloterm{filebuf.general}}{\memglodesc{(\ref {filebuf.general})}} {\memgloref{}}|memjustarg}{1688} -\glossaryentry{filebuf.cons@ {\memgloterm{filebuf.cons}}{\memglodesc{(\ref {filebuf.cons})}} {\memgloref{}}|memjustarg}{1689} -\glossaryentry{filebuf.assign@ {\memgloterm{filebuf.assign}}{\memglodesc{(\ref {filebuf.assign})}} {\memgloref{}}|memjustarg}{1690} -\glossaryentry{filebuf.members@ {\memgloterm{filebuf.members}}{\memglodesc{(\ref {filebuf.members})}} {\memgloref{}}|memjustarg}{1690} -\glossaryentry{filebuf.virtuals@ {\memgloterm{filebuf.virtuals}}{\memglodesc{(\ref {filebuf.virtuals})}} {\memgloref{}}|memjustarg}{1691} -\glossaryentry{ifstream@ {\memgloterm{ifstream}}{\memglodesc{(\ref {ifstream})}} {\memgloref{}}|memjustarg}{1693} -\glossaryentry{ifstream.general@ {\memgloterm{ifstream.general}}{\memglodesc{(\ref {ifstream.general})}} {\memgloref{}}|memjustarg}{1693} -\glossaryentry{ifstream.cons@ {\memgloterm{ifstream.cons}}{\memglodesc{(\ref {ifstream.cons})}} {\memgloref{}}|memjustarg}{1694} -\glossaryentry{ifstream.swap@ {\memgloterm{ifstream.swap}}{\memglodesc{(\ref {ifstream.swap})}} {\memgloref{}}|memjustarg}{1695} -\glossaryentry{ifstream.members@ {\memgloterm{ifstream.members}}{\memglodesc{(\ref {ifstream.members})}} {\memgloref{}}|memjustarg}{1695} -\glossaryentry{ofstream@ {\memgloterm{ofstream}}{\memglodesc{(\ref {ofstream})}} {\memgloref{}}|memjustarg}{1695} -\glossaryentry{ofstream.general@ {\memgloterm{ofstream.general}}{\memglodesc{(\ref {ofstream.general})}} {\memgloref{}}|memjustarg}{1695} -\glossaryentry{ofstream.cons@ {\memgloterm{ofstream.cons}}{\memglodesc{(\ref {ofstream.cons})}} {\memgloref{}}|memjustarg}{1696} -\glossaryentry{ofstream.swap@ {\memgloterm{ofstream.swap}}{\memglodesc{(\ref {ofstream.swap})}} {\memgloref{}}|memjustarg}{1697} -\glossaryentry{ofstream.members@ {\memgloterm{ofstream.members}}{\memglodesc{(\ref {ofstream.members})}} {\memgloref{}}|memjustarg}{1697} -\glossaryentry{fstream@ {\memgloterm{fstream}}{\memglodesc{(\ref {fstream})}} {\memgloref{}}|memjustarg}{1697} -\glossaryentry{fstream.general@ {\memgloterm{fstream.general}}{\memglodesc{(\ref {fstream.general})}} {\memgloref{}}|memjustarg}{1697} -\glossaryentry{fstream.cons@ {\memgloterm{fstream.cons}}{\memglodesc{(\ref {fstream.cons})}} {\memgloref{}}|memjustarg}{1698} -\glossaryentry{fstream.swap@ {\memgloterm{fstream.swap}}{\memglodesc{(\ref {fstream.swap})}} {\memgloref{}}|memjustarg}{1699} -\glossaryentry{fstream.members@ {\memgloterm{fstream.members}}{\memglodesc{(\ref {fstream.members})}} {\memgloref{}}|memjustarg}{1699} -\glossaryentry{syncstream@ {\memgloterm{syncstream}}{\memglodesc{(\ref {syncstream})}} {\memgloref{}}|memjustarg}{1699} -\glossaryentry{syncstream.syn@ {\memgloterm{syncstream.syn}}{\memglodesc{(\ref {syncstream.syn})}} {\memgloref{}}|memjustarg}{1699} -\glossaryentry{syncstream.syncbuf@ {\memgloterm{syncstream.syncbuf}}{\memglodesc{(\ref {syncstream.syncbuf})}} {\memgloref{}}|memjustarg}{1700} -\glossaryentry{syncstream.syncbuf.overview@ {\memgloterm{syncstream.syncbuf.overview}}{\memglodesc{(\ref {syncstream.syncbuf.overview})}} {\memgloref{}}|memjustarg}{1700} -\glossaryentry{syncstream.syncbuf.cons@ {\memgloterm{syncstream.syncbuf.cons}}{\memglodesc{(\ref {syncstream.syncbuf.cons})}} {\memgloref{}}|memjustarg}{1700} -\glossaryentry{syncstream.syncbuf.assign@ {\memgloterm{syncstream.syncbuf.assign}}{\memglodesc{(\ref {syncstream.syncbuf.assign})}} {\memgloref{}}|memjustarg}{1701} -\glossaryentry{syncstream.syncbuf.members@ {\memgloterm{syncstream.syncbuf.members}}{\memglodesc{(\ref {syncstream.syncbuf.members})}} {\memgloref{}}|memjustarg}{1701} -\glossaryentry{syncstream.syncbuf.virtuals@ {\memgloterm{syncstream.syncbuf.virtuals}}{\memglodesc{(\ref {syncstream.syncbuf.virtuals})}} {\memgloref{}}|memjustarg}{1702} -\glossaryentry{syncstream.syncbuf.special@ {\memgloterm{syncstream.syncbuf.special}}{\memglodesc{(\ref {syncstream.syncbuf.special})}} {\memgloref{}}|memjustarg}{1702} -\glossaryentry{syncstream.osyncstream@ {\memgloterm{syncstream.osyncstream}}{\memglodesc{(\ref {syncstream.osyncstream})}} {\memgloref{}}|memjustarg}{1702} -\glossaryentry{syncstream.osyncstream.overview@ {\memgloterm{syncstream.osyncstream.overview}}{\memglodesc{(\ref {syncstream.osyncstream.overview})}} {\memgloref{}}|memjustarg}{1702} -\glossaryentry{syncstream.osyncstream.cons@ {\memgloterm{syncstream.osyncstream.cons}}{\memglodesc{(\ref {syncstream.osyncstream.cons})}} {\memgloref{}}|memjustarg}{1703} -\glossaryentry{syncstream.osyncstream.members@ {\memgloterm{syncstream.osyncstream.members}}{\memglodesc{(\ref {syncstream.osyncstream.members})}} {\memgloref{}}|memjustarg}{1703} -\glossaryentry{filesystems@ {\memgloterm{filesystems}}{\memglodesc{(\ref {filesystems})}} {\memgloref{}}|memjustarg}{1704} -\glossaryentry{fs.general@ {\memgloterm{fs.general}}{\memglodesc{(\ref {fs.general})}} {\memgloref{}}|memjustarg}{1704} -\glossaryentry{fs.conformance@ {\memgloterm{fs.conformance}}{\memglodesc{(\ref {fs.conformance})}} {\memgloref{}}|memjustarg}{1704} -\glossaryentry{fs.conformance.general@ {\memgloterm{fs.conformance.general}}{\memglodesc{(\ref {fs.conformance.general})}} {\memgloref{}}|memjustarg}{1704} -\glossaryentry{fs.conform.9945@ {\memgloterm{fs.conform.9945}}{\memglodesc{(\ref {fs.conform.9945})}} {\memgloref{}}|memjustarg}{1704} -\glossaryentry{fs.conform.os@ {\memgloterm{fs.conform.os}}{\memglodesc{(\ref {fs.conform.os})}} {\memgloref{}}|memjustarg}{1705} -\glossaryentry{fs.race.behavior@ {\memgloterm{fs.race.behavior}}{\memglodesc{(\ref {fs.race.behavior})}} {\memgloref{}}|memjustarg}{1705} -\glossaryentry{fs.req@ {\memgloterm{fs.req}}{\memglodesc{(\ref {fs.req})}} {\memgloref{}}|memjustarg}{1705} -\glossaryentry{fs.filesystem.syn@ {\memgloterm{fs.filesystem.syn}}{\memglodesc{(\ref {fs.filesystem.syn})}} {\memgloref{}}|memjustarg}{1705} -\glossaryentry{fs.err.report@ {\memgloterm{fs.err.report}}{\memglodesc{(\ref {fs.err.report})}} {\memgloref{}}|memjustarg}{1709} -\glossaryentry{fs.class.path@ {\memgloterm{fs.class.path}}{\memglodesc{(\ref {fs.class.path})}} {\memgloref{}}|memjustarg}{1709} -\glossaryentry{fs.class.path.general@ {\memgloterm{fs.class.path.general}}{\memglodesc{(\ref {fs.class.path.general})}} {\memgloref{}}|memjustarg}{1709} -\glossaryentry{fs.path.generic@ {\memgloterm{fs.path.generic}}{\memglodesc{(\ref {fs.path.generic})}} {\memgloref{}}|memjustarg}{1712} -\glossaryentry{fs.path.cvt@ {\memgloterm{fs.path.cvt}}{\memglodesc{(\ref {fs.path.cvt})}} {\memgloref{}}|memjustarg}{1714} -\glossaryentry{fs.path.fmt.cvt@ {\memgloterm{fs.path.fmt.cvt}}{\memglodesc{(\ref {fs.path.fmt.cvt})}} {\memgloref{}}|memjustarg}{1714} -\glossaryentry{fs.path.type.cvt@ {\memgloterm{fs.path.type.cvt}}{\memglodesc{(\ref {fs.path.type.cvt})}} {\memgloref{}}|memjustarg}{1714} -\glossaryentry{fs.path.req@ {\memgloterm{fs.path.req}}{\memglodesc{(\ref {fs.path.req})}} {\memgloref{}}|memjustarg}{1715} -\glossaryentry{fs.path.member@ {\memgloterm{fs.path.member}}{\memglodesc{(\ref {fs.path.member})}} {\memgloref{}}|memjustarg}{1715} -\glossaryentry{fs.path.construct@ {\memgloterm{fs.path.construct}}{\memglodesc{(\ref {fs.path.construct})}} {\memgloref{}}|memjustarg}{1715} -\glossaryentry{fs.path.assign@ {\memgloterm{fs.path.assign}}{\memglodesc{(\ref {fs.path.assign})}} {\memgloref{}}|memjustarg}{1716} -\glossaryentry{fs.path.append@ {\memgloterm{fs.path.append}}{\memglodesc{(\ref {fs.path.append})}} {\memgloref{}}|memjustarg}{1717} -\glossaryentry{fs.path.concat@ {\memgloterm{fs.path.concat}}{\memglodesc{(\ref {fs.path.concat})}} {\memgloref{}}|memjustarg}{1717} -\glossaryentry{fs.path.modifiers@ {\memgloterm{fs.path.modifiers}}{\memglodesc{(\ref {fs.path.modifiers})}} {\memgloref{}}|memjustarg}{1718} -\glossaryentry{fs.path.native.obs@ {\memgloterm{fs.path.native.obs}}{\memglodesc{(\ref {fs.path.native.obs})}} {\memgloref{}}|memjustarg}{1719} -\glossaryentry{fs.path.generic.obs@ {\memgloterm{fs.path.generic.obs}}{\memglodesc{(\ref {fs.path.generic.obs})}} {\memgloref{}}|memjustarg}{1719} -\glossaryentry{fs.path.compare@ {\memgloterm{fs.path.compare}}{\memglodesc{(\ref {fs.path.compare})}} {\memgloref{}}|memjustarg}{1720} -\glossaryentry{fs.path.decompose@ {\memgloterm{fs.path.decompose}}{\memglodesc{(\ref {fs.path.decompose})}} {\memgloref{}}|memjustarg}{1720} -\glossaryentry{fs.path.query@ {\memgloterm{fs.path.query}}{\memglodesc{(\ref {fs.path.query})}} {\memgloref{}}|memjustarg}{1721} -\glossaryentry{fs.path.gen@ {\memgloterm{fs.path.gen}}{\memglodesc{(\ref {fs.path.gen})}} {\memgloref{}}|memjustarg}{1722} -\glossaryentry{fs.path.itr@ {\memgloterm{fs.path.itr}}{\memglodesc{(\ref {fs.path.itr})}} {\memgloref{}}|memjustarg}{1723} -\glossaryentry{fs.path.io@ {\memgloterm{fs.path.io}}{\memglodesc{(\ref {fs.path.io})}} {\memgloref{}}|memjustarg}{1723} -\glossaryentry{fs.path.nonmember@ {\memgloterm{fs.path.nonmember}}{\memglodesc{(\ref {fs.path.nonmember})}} {\memgloref{}}|memjustarg}{1724} -\glossaryentry{fs.path.hash@ {\memgloterm{fs.path.hash}}{\memglodesc{(\ref {fs.path.hash})}} {\memgloref{}}|memjustarg}{1724} -\glossaryentry{fs.class.filesystem.error@ {\memgloterm{fs.class.filesystem.error}}{\memglodesc{(\ref {fs.class.filesystem.error})}} {\memgloref{}}|memjustarg}{1724} -\glossaryentry{fs.class.filesystem.error.general@ {\memgloterm{fs.class.filesystem.error.general}}{\memglodesc{(\ref {fs.class.filesystem.error.general})}} {\memgloref{}}|memjustarg}{1724} -\glossaryentry{fs.filesystem.error.members@ {\memgloterm{fs.filesystem.error.members}}{\memglodesc{(\ref {fs.filesystem.error.members})}} {\memgloref{}}|memjustarg}{1724} -\glossaryentry{fs.enum@ {\memgloterm{fs.enum}}{\memglodesc{(\ref {fs.enum})}} {\memgloref{}}|memjustarg}{1725} -\glossaryentry{fs.enum.path.format@ {\memgloterm{fs.enum.path.format}}{\memglodesc{(\ref {fs.enum.path.format})}} {\memgloref{}}|memjustarg}{1725} -\glossaryentry{fs.enum.file.type@ {\memgloterm{fs.enum.file.type}}{\memglodesc{(\ref {fs.enum.file.type})}} {\memgloref{}}|memjustarg}{1725} -\glossaryentry{fs.enum.copy.opts@ {\memgloterm{fs.enum.copy.opts}}{\memglodesc{(\ref {fs.enum.copy.opts})}} {\memgloref{}}|memjustarg}{1726} -\glossaryentry{fs.enum.perms@ {\memgloterm{fs.enum.perms}}{\memglodesc{(\ref {fs.enum.perms})}} {\memgloref{}}|memjustarg}{1727} -\glossaryentry{fs.enum.perm.opts@ {\memgloterm{fs.enum.perm.opts}}{\memglodesc{(\ref {fs.enum.perm.opts})}} {\memgloref{}}|memjustarg}{1727} -\glossaryentry{fs.enum.dir.opts@ {\memgloterm{fs.enum.dir.opts}}{\memglodesc{(\ref {fs.enum.dir.opts})}} {\memgloref{}}|memjustarg}{1727} -\glossaryentry{fs.class.file.status@ {\memgloterm{fs.class.file.status}}{\memglodesc{(\ref {fs.class.file.status})}} {\memgloref{}}|memjustarg}{1728} -\glossaryentry{fs.class.file.status.general@ {\memgloterm{fs.class.file.status.general}}{\memglodesc{(\ref {fs.class.file.status.general})}} {\memgloref{}}|memjustarg}{1728} -\glossaryentry{fs.file.status.cons@ {\memgloterm{fs.file.status.cons}}{\memglodesc{(\ref {fs.file.status.cons})}} {\memgloref{}}|memjustarg}{1728} -\glossaryentry{fs.file.status.obs@ {\memgloterm{fs.file.status.obs}}{\memglodesc{(\ref {fs.file.status.obs})}} {\memgloref{}}|memjustarg}{1728} -\glossaryentry{fs.file.status.mods@ {\memgloterm{fs.file.status.mods}}{\memglodesc{(\ref {fs.file.status.mods})}} {\memgloref{}}|memjustarg}{1728} -\glossaryentry{fs.class.directory.entry@ {\memgloterm{fs.class.directory.entry}}{\memglodesc{(\ref {fs.class.directory.entry})}} {\memgloref{}}|memjustarg}{1729} -\glossaryentry{fs.class.directory.entry.general@ {\memgloterm{fs.class.directory.entry.general}}{\memglodesc{(\ref {fs.class.directory.entry.general})}} {\memgloref{}}|memjustarg}{1729} -\glossaryentry{fs.dir.entry.cons@ {\memgloterm{fs.dir.entry.cons}}{\memglodesc{(\ref {fs.dir.entry.cons})}} {\memgloref{}}|memjustarg}{1730} -\glossaryentry{fs.dir.entry.mods@ {\memgloterm{fs.dir.entry.mods}}{\memglodesc{(\ref {fs.dir.entry.mods})}} {\memgloref{}}|memjustarg}{1730} -\glossaryentry{fs.dir.entry.obs@ {\memgloterm{fs.dir.entry.obs}}{\memglodesc{(\ref {fs.dir.entry.obs})}} {\memgloref{}}|memjustarg}{1731} -\glossaryentry{fs.dir.entry.io@ {\memgloterm{fs.dir.entry.io}}{\memglodesc{(\ref {fs.dir.entry.io})}} {\memgloref{}}|memjustarg}{1732} -\glossaryentry{fs.class.directory.iterator@ {\memgloterm{fs.class.directory.iterator}}{\memglodesc{(\ref {fs.class.directory.iterator})}} {\memgloref{}}|memjustarg}{1733} -\glossaryentry{fs.class.directory.iterator.general@ {\memgloterm{fs.class.directory.iterator.general}}{\memglodesc{(\ref {fs.class.directory.iterator.general})}} {\memgloref{}}|memjustarg}{1733} -\glossaryentry{fs.dir.itr.members@ {\memgloterm{fs.dir.itr.members}}{\memglodesc{(\ref {fs.dir.itr.members})}} {\memgloref{}}|memjustarg}{1734} -\glossaryentry{fs.dir.itr.nonmembers@ {\memgloterm{fs.dir.itr.nonmembers}}{\memglodesc{(\ref {fs.dir.itr.nonmembers})}} {\memgloref{}}|memjustarg}{1734} -\glossaryentry{fs.class.rec.dir.itr@ {\memgloterm{fs.class.rec.dir.itr}}{\memglodesc{(\ref {fs.class.rec.dir.itr})}} {\memgloref{}}|memjustarg}{1735} -\glossaryentry{fs.class.rec.dir.itr.general@ {\memgloterm{fs.class.rec.dir.itr.general}}{\memglodesc{(\ref {fs.class.rec.dir.itr.general})}} {\memgloref{}}|memjustarg}{1735} -\glossaryentry{fs.rec.dir.itr.members@ {\memgloterm{fs.rec.dir.itr.members}}{\memglodesc{(\ref {fs.rec.dir.itr.members})}} {\memgloref{}}|memjustarg}{1736} -\glossaryentry{fs.rec.dir.itr.nonmembers@ {\memgloterm{fs.rec.dir.itr.nonmembers}}{\memglodesc{(\ref {fs.rec.dir.itr.nonmembers})}} {\memgloref{}}|memjustarg}{1737} -\glossaryentry{fs.op.funcs@ {\memgloterm{fs.op.funcs}}{\memglodesc{(\ref {fs.op.funcs})}} {\memgloref{}}|memjustarg}{1737} -\glossaryentry{fs.op.funcs.general@ {\memgloterm{fs.op.funcs.general}}{\memglodesc{(\ref {fs.op.funcs.general})}} {\memgloref{}}|memjustarg}{1737} -\glossaryentry{fs.op.absolute@ {\memgloterm{fs.op.absolute}}{\memglodesc{(\ref {fs.op.absolute})}} {\memgloref{}}|memjustarg}{1737} -\glossaryentry{fs.op.canonical@ {\memgloterm{fs.op.canonical}}{\memglodesc{(\ref {fs.op.canonical})}} {\memgloref{}}|memjustarg}{1738} -\glossaryentry{fs.op.copy@ {\memgloterm{fs.op.copy}}{\memglodesc{(\ref {fs.op.copy})}} {\memgloref{}}|memjustarg}{1738} -\glossaryentry{fs.op.copy.file@ {\memgloterm{fs.op.copy.file}}{\memglodesc{(\ref {fs.op.copy.file})}} {\memgloref{}}|memjustarg}{1740} -\glossaryentry{fs.op.copy.symlink@ {\memgloterm{fs.op.copy.symlink}}{\memglodesc{(\ref {fs.op.copy.symlink})}} {\memgloref{}}|memjustarg}{1740} -\glossaryentry{fs.op.create.directories@ {\memgloterm{fs.op.create.directories}}{\memglodesc{(\ref {fs.op.create.directories})}} {\memgloref{}}|memjustarg}{1741} -\glossaryentry{fs.op.create.directory@ {\memgloterm{fs.op.create.directory}}{\memglodesc{(\ref {fs.op.create.directory})}} {\memgloref{}}|memjustarg}{1741} -\glossaryentry{fs.op.create.dir.symlk@ {\memgloterm{fs.op.create.dir.symlk}}{\memglodesc{(\ref {fs.op.create.dir.symlk})}} {\memgloref{}}|memjustarg}{1741} -\glossaryentry{fs.op.create.hard.lk@ {\memgloterm{fs.op.create.hard.lk}}{\memglodesc{(\ref {fs.op.create.hard.lk})}} {\memgloref{}}|memjustarg}{1742} -\glossaryentry{fs.op.create.symlink@ {\memgloterm{fs.op.create.symlink}}{\memglodesc{(\ref {fs.op.create.symlink})}} {\memgloref{}}|memjustarg}{1742} -\glossaryentry{fs.op.current.path@ {\memgloterm{fs.op.current.path}}{\memglodesc{(\ref {fs.op.current.path})}} {\memgloref{}}|memjustarg}{1742} -\glossaryentry{fs.op.equivalent@ {\memgloterm{fs.op.equivalent}}{\memglodesc{(\ref {fs.op.equivalent})}} {\memgloref{}}|memjustarg}{1742} -\glossaryentry{fs.op.exists@ {\memgloterm{fs.op.exists}}{\memglodesc{(\ref {fs.op.exists})}} {\memgloref{}}|memjustarg}{1743} -\glossaryentry{fs.op.file.size@ {\memgloterm{fs.op.file.size}}{\memglodesc{(\ref {fs.op.file.size})}} {\memgloref{}}|memjustarg}{1743} -\glossaryentry{fs.op.hard.lk.ct@ {\memgloterm{fs.op.hard.lk.ct}}{\memglodesc{(\ref {fs.op.hard.lk.ct})}} {\memgloref{}}|memjustarg}{1743} -\glossaryentry{fs.op.is.block.file@ {\memgloterm{fs.op.is.block.file}}{\memglodesc{(\ref {fs.op.is.block.file})}} {\memgloref{}}|memjustarg}{1743} -\glossaryentry{fs.op.is.char.file@ {\memgloterm{fs.op.is.char.file}}{\memglodesc{(\ref {fs.op.is.char.file})}} {\memgloref{}}|memjustarg}{1743} -\glossaryentry{fs.op.is.directory@ {\memgloterm{fs.op.is.directory}}{\memglodesc{(\ref {fs.op.is.directory})}} {\memgloref{}}|memjustarg}{1744} -\glossaryentry{fs.op.is.empty@ {\memgloterm{fs.op.is.empty}}{\memglodesc{(\ref {fs.op.is.empty})}} {\memgloref{}}|memjustarg}{1744} -\glossaryentry{fs.op.is.fifo@ {\memgloterm{fs.op.is.fifo}}{\memglodesc{(\ref {fs.op.is.fifo})}} {\memgloref{}}|memjustarg}{1744} -\glossaryentry{fs.op.is.other@ {\memgloterm{fs.op.is.other}}{\memglodesc{(\ref {fs.op.is.other})}} {\memgloref{}}|memjustarg}{1744} -\glossaryentry{fs.op.is.regular.file@ {\memgloterm{fs.op.is.regular.file}}{\memglodesc{(\ref {fs.op.is.regular.file})}} {\memgloref{}}|memjustarg}{1745} -\glossaryentry{fs.op.is.socket@ {\memgloterm{fs.op.is.socket}}{\memglodesc{(\ref {fs.op.is.socket})}} {\memgloref{}}|memjustarg}{1745} -\glossaryentry{fs.op.is.symlink@ {\memgloterm{fs.op.is.symlink}}{\memglodesc{(\ref {fs.op.is.symlink})}} {\memgloref{}}|memjustarg}{1745} -\glossaryentry{fs.op.last.write.time@ {\memgloterm{fs.op.last.write.time}}{\memglodesc{(\ref {fs.op.last.write.time})}} {\memgloref{}}|memjustarg}{1745} -\glossaryentry{fs.op.permissions@ {\memgloterm{fs.op.permissions}}{\memglodesc{(\ref {fs.op.permissions})}} {\memgloref{}}|memjustarg}{1746} -\glossaryentry{fs.op.proximate@ {\memgloterm{fs.op.proximate}}{\memglodesc{(\ref {fs.op.proximate})}} {\memgloref{}}|memjustarg}{1746} -\glossaryentry{fs.op.read.symlink@ {\memgloterm{fs.op.read.symlink}}{\memglodesc{(\ref {fs.op.read.symlink})}} {\memgloref{}}|memjustarg}{1746} -\glossaryentry{fs.op.relative@ {\memgloterm{fs.op.relative}}{\memglodesc{(\ref {fs.op.relative})}} {\memgloref{}}|memjustarg}{1746} -\glossaryentry{fs.op.remove@ {\memgloterm{fs.op.remove}}{\memglodesc{(\ref {fs.op.remove})}} {\memgloref{}}|memjustarg}{1747} -\glossaryentry{fs.op.remove.all@ {\memgloterm{fs.op.remove.all}}{\memglodesc{(\ref {fs.op.remove.all})}} {\memgloref{}}|memjustarg}{1747} -\glossaryentry{fs.op.rename@ {\memgloterm{fs.op.rename}}{\memglodesc{(\ref {fs.op.rename})}} {\memgloref{}}|memjustarg}{1747} -\glossaryentry{fs.op.resize.file@ {\memgloterm{fs.op.resize.file}}{\memglodesc{(\ref {fs.op.resize.file})}} {\memgloref{}}|memjustarg}{1747} -\glossaryentry{fs.op.space@ {\memgloterm{fs.op.space}}{\memglodesc{(\ref {fs.op.space})}} {\memgloref{}}|memjustarg}{1747} -\glossaryentry{fs.op.status@ {\memgloterm{fs.op.status}}{\memglodesc{(\ref {fs.op.status})}} {\memgloref{}}|memjustarg}{1748} -\glossaryentry{fs.op.status.known@ {\memgloterm{fs.op.status.known}}{\memglodesc{(\ref {fs.op.status.known})}} {\memgloref{}}|memjustarg}{1749} -\glossaryentry{fs.op.symlink.status@ {\memgloterm{fs.op.symlink.status}}{\memglodesc{(\ref {fs.op.symlink.status})}} {\memgloref{}}|memjustarg}{1749} -\glossaryentry{fs.op.temp.dir.path@ {\memgloterm{fs.op.temp.dir.path}}{\memglodesc{(\ref {fs.op.temp.dir.path})}} {\memgloref{}}|memjustarg}{1749} -\glossaryentry{fs.op.weakly.canonical@ {\memgloterm{fs.op.weakly.canonical}}{\memglodesc{(\ref {fs.op.weakly.canonical})}} {\memgloref{}}|memjustarg}{1749} -\glossaryentry{c.files@ {\memgloterm{c.files}}{\memglodesc{(\ref {c.files})}} {\memgloref{}}|memjustarg}{1750} -\glossaryentry{cstdio.syn@ {\memgloterm{cstdio.syn}}{\memglodesc{(\ref {cstdio.syn})}} {\memgloref{}}|memjustarg}{1750} -\glossaryentry{cinttypes.syn@ {\memgloterm{cinttypes.syn}}{\memglodesc{(\ref {cinttypes.syn})}} {\memgloref{}}|memjustarg}{1751} -\glossaryentry{re@ {\memgloterm{re}}{\memglodesc{(\ref {re})}} {\memgloref{}}|memjustarg}{1753} -\glossaryentry{re.general@ {\memgloterm{re.general}}{\memglodesc{(\ref {re.general})}} {\memgloref{}}|memjustarg}{1753} -\glossaryentry{re.req@ {\memgloterm{re.req}}{\memglodesc{(\ref {re.req})}} {\memgloref{}}|memjustarg}{1753} -\glossaryentry{re.syn@ {\memgloterm{re.syn}}{\memglodesc{(\ref {re.syn})}} {\memgloref{}}|memjustarg}{1755} -\glossaryentry{re.const@ {\memgloterm{re.const}}{\memglodesc{(\ref {re.const})}} {\memgloref{}}|memjustarg}{1759} -\glossaryentry{re.const.general@ {\memgloterm{re.const.general}}{\memglodesc{(\ref {re.const.general})}} {\memgloref{}}|memjustarg}{1759} -\glossaryentry{re.synopt@ {\memgloterm{re.synopt}}{\memglodesc{(\ref {re.synopt})}} {\memgloref{}}|memjustarg}{1759} -\glossaryentry{re.matchflag@ {\memgloterm{re.matchflag}}{\memglodesc{(\ref {re.matchflag})}} {\memgloref{}}|memjustarg}{1759} -\glossaryentry{re.err@ {\memgloterm{re.err}}{\memglodesc{(\ref {re.err})}} {\memgloref{}}|memjustarg}{1761} -\glossaryentry{re.badexp@ {\memgloterm{re.badexp}}{\memglodesc{(\ref {re.badexp})}} {\memgloref{}}|memjustarg}{1761} -\glossaryentry{re.traits@ {\memgloterm{re.traits}}{\memglodesc{(\ref {re.traits})}} {\memgloref{}}|memjustarg}{1762} -\glossaryentry{re.regex@ {\memgloterm{re.regex}}{\memglodesc{(\ref {re.regex})}} {\memgloref{}}|memjustarg}{1764} -\glossaryentry{re.regex.general@ {\memgloterm{re.regex.general}}{\memglodesc{(\ref {re.regex.general})}} {\memgloref{}}|memjustarg}{1764} -\glossaryentry{re.regex.construct@ {\memgloterm{re.regex.construct}}{\memglodesc{(\ref {re.regex.construct})}} {\memgloref{}}|memjustarg}{1766} -\glossaryentry{re.regex.assign@ {\memgloterm{re.regex.assign}}{\memglodesc{(\ref {re.regex.assign})}} {\memgloref{}}|memjustarg}{1767} -\glossaryentry{re.regex.operations@ {\memgloterm{re.regex.operations}}{\memglodesc{(\ref {re.regex.operations})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.regex.locale@ {\memgloterm{re.regex.locale}}{\memglodesc{(\ref {re.regex.locale})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.regex.swap@ {\memgloterm{re.regex.swap}}{\memglodesc{(\ref {re.regex.swap})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.regex.nonmemb@ {\memgloterm{re.regex.nonmemb}}{\memglodesc{(\ref {re.regex.nonmemb})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.submatch@ {\memgloterm{re.submatch}}{\memglodesc{(\ref {re.submatch})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.submatch.general@ {\memgloterm{re.submatch.general}}{\memglodesc{(\ref {re.submatch.general})}} {\memgloref{}}|memjustarg}{1768} -\glossaryentry{re.submatch.members@ {\memgloterm{re.submatch.members}}{\memglodesc{(\ref {re.submatch.members})}} {\memgloref{}}|memjustarg}{1769} -\glossaryentry{re.submatch.op@ {\memgloterm{re.submatch.op}}{\memglodesc{(\ref {re.submatch.op})}} {\memgloref{}}|memjustarg}{1769} -\glossaryentry{re.results@ {\memgloterm{re.results}}{\memglodesc{(\ref {re.results})}} {\memgloref{}}|memjustarg}{1770} -\glossaryentry{re.results.general@ {\memgloterm{re.results.general}}{\memglodesc{(\ref {re.results.general})}} {\memgloref{}}|memjustarg}{1770} -\glossaryentry{re.results.const@ {\memgloterm{re.results.const}}{\memglodesc{(\ref {re.results.const})}} {\memgloref{}}|memjustarg}{1772} -\glossaryentry{re.results.state@ {\memgloterm{re.results.state}}{\memglodesc{(\ref {re.results.state})}} {\memgloref{}}|memjustarg}{1772} -\glossaryentry{re.results.size@ {\memgloterm{re.results.size}}{\memglodesc{(\ref {re.results.size})}} {\memgloref{}}|memjustarg}{1773} -\glossaryentry{re.results.acc@ {\memgloterm{re.results.acc}}{\memglodesc{(\ref {re.results.acc})}} {\memgloref{}}|memjustarg}{1773} -\glossaryentry{re.results.form@ {\memgloterm{re.results.form}}{\memglodesc{(\ref {re.results.form})}} {\memgloref{}}|memjustarg}{1774} -\glossaryentry{re.results.all@ {\memgloterm{re.results.all}}{\memglodesc{(\ref {re.results.all})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.results.swap@ {\memgloterm{re.results.swap}}{\memglodesc{(\ref {re.results.swap})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.results.nonmember@ {\memgloterm{re.results.nonmember}}{\memglodesc{(\ref {re.results.nonmember})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.alg@ {\memgloterm{re.alg}}{\memglodesc{(\ref {re.alg})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.except@ {\memgloterm{re.except}}{\memglodesc{(\ref {re.except})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.alg.match@ {\memgloterm{re.alg.match}}{\memglodesc{(\ref {re.alg.match})}} {\memgloref{}}|memjustarg}{1775} -\glossaryentry{re.alg.search@ {\memgloterm{re.alg.search}}{\memglodesc{(\ref {re.alg.search})}} {\memgloref{}}|memjustarg}{1777} -\glossaryentry{re.alg.replace@ {\memgloterm{re.alg.replace}}{\memglodesc{(\ref {re.alg.replace})}} {\memgloref{}}|memjustarg}{1778} -\glossaryentry{re.iter@ {\memgloterm{re.iter}}{\memglodesc{(\ref {re.iter})}} {\memgloref{}}|memjustarg}{1779} -\glossaryentry{re.regiter@ {\memgloterm{re.regiter}}{\memglodesc{(\ref {re.regiter})}} {\memgloref{}}|memjustarg}{1779} -\glossaryentry{re.regiter.general@ {\memgloterm{re.regiter.general}}{\memglodesc{(\ref {re.regiter.general})}} {\memgloref{}}|memjustarg}{1779} -\glossaryentry{re.regiter.cnstr@ {\memgloterm{re.regiter.cnstr}}{\memglodesc{(\ref {re.regiter.cnstr})}} {\memgloref{}}|memjustarg}{1780} -\glossaryentry{re.regiter.comp@ {\memgloterm{re.regiter.comp}}{\memglodesc{(\ref {re.regiter.comp})}} {\memgloref{}}|memjustarg}{1780} -\glossaryentry{re.regiter.deref@ {\memgloterm{re.regiter.deref}}{\memglodesc{(\ref {re.regiter.deref})}} {\memgloref{}}|memjustarg}{1781} -\glossaryentry{re.regiter.incr@ {\memgloterm{re.regiter.incr}}{\memglodesc{(\ref {re.regiter.incr})}} {\memgloref{}}|memjustarg}{1781} -\glossaryentry{re.tokiter@ {\memgloterm{re.tokiter}}{\memglodesc{(\ref {re.tokiter})}} {\memgloref{}}|memjustarg}{1781} -\glossaryentry{re.tokiter.general@ {\memgloterm{re.tokiter.general}}{\memglodesc{(\ref {re.tokiter.general})}} {\memgloref{}}|memjustarg}{1781} -\glossaryentry{re.tokiter.cnstr@ {\memgloterm{re.tokiter.cnstr}}{\memglodesc{(\ref {re.tokiter.cnstr})}} {\memgloref{}}|memjustarg}{1783} -\glossaryentry{re.tokiter.comp@ {\memgloterm{re.tokiter.comp}}{\memglodesc{(\ref {re.tokiter.comp})}} {\memgloref{}}|memjustarg}{1784} -\glossaryentry{re.tokiter.deref@ {\memgloterm{re.tokiter.deref}}{\memglodesc{(\ref {re.tokiter.deref})}} {\memgloref{}}|memjustarg}{1784} -\glossaryentry{re.tokiter.incr@ {\memgloterm{re.tokiter.incr}}{\memglodesc{(\ref {re.tokiter.incr})}} {\memgloref{}}|memjustarg}{1784} -\glossaryentry{re.grammar@ {\memgloterm{re.grammar}}{\memglodesc{(\ref {re.grammar})}} {\memgloref{}}|memjustarg}{1785} -\glossaryentry{thread@ {\memgloterm{thread}}{\memglodesc{(\ref {thread})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.general@ {\memgloterm{thread.general}}{\memglodesc{(\ref {thread.general})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req@ {\memgloterm{thread.req}}{\memglodesc{(\ref {thread.req})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req.paramname@ {\memgloterm{thread.req.paramname}}{\memglodesc{(\ref {thread.req.paramname})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req.exception@ {\memgloterm{thread.req.exception}}{\memglodesc{(\ref {thread.req.exception})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req.native@ {\memgloterm{thread.req.native}}{\memglodesc{(\ref {thread.req.native})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req.timing@ {\memgloterm{thread.req.timing}}{\memglodesc{(\ref {thread.req.timing})}} {\memgloref{}}|memjustarg}{1787} -\glossaryentry{thread.req.lockable@ {\memgloterm{thread.req.lockable}}{\memglodesc{(\ref {thread.req.lockable})}} {\memgloref{}}|memjustarg}{1788} -\glossaryentry{thread.req.lockable.general@ {\memgloterm{thread.req.lockable.general}}{\memglodesc{(\ref {thread.req.lockable.general})}} {\memgloref{}}|memjustarg}{1788} -\glossaryentry{thread.req.lockable.basic@ {\memgloterm{thread.req.lockable.basic}}{\memglodesc{(\ref {thread.req.lockable.basic})}} {\memgloref{}}|memjustarg}{1789} -\glossaryentry{thread.req.lockable.req@ {\memgloterm{thread.req.lockable.req}}{\memglodesc{(\ref {thread.req.lockable.req})}} {\memgloref{}}|memjustarg}{1789} -\glossaryentry{thread.req.lockable.timed@ {\memgloterm{thread.req.lockable.timed}}{\memglodesc{(\ref {thread.req.lockable.timed})}} {\memgloref{}}|memjustarg}{1789} -\glossaryentry{thread.req.lockable.shared@ {\memgloterm{thread.req.lockable.shared}}{\memglodesc{(\ref {thread.req.lockable.shared})}} {\memgloref{}}|memjustarg}{1790} -\glossaryentry{thread.req.lockable.shared.timed@ {\memgloterm{thread.req.lockable.shared.timed}}{\memglodesc{(\ref {thread.req.lockable.shared.timed})}} {\memgloref{}}|memjustarg}{1790} -\glossaryentry{thread.stoptoken@ {\memgloterm{thread.stoptoken}}{\memglodesc{(\ref {thread.stoptoken})}} {\memgloref{}}|memjustarg}{1790} -\glossaryentry{thread.stoptoken.intro@ {\memgloterm{thread.stoptoken.intro}}{\memglodesc{(\ref {thread.stoptoken.intro})}} {\memgloref{}}|memjustarg}{1790} -\glossaryentry{thread.stoptoken.syn@ {\memgloterm{thread.stoptoken.syn}}{\memglodesc{(\ref {thread.stoptoken.syn})}} {\memgloref{}}|memjustarg}{1791} -\glossaryentry{stoptoken@ {\memgloterm{stoptoken}}{\memglodesc{(\ref {stoptoken})}} {\memgloref{}}|memjustarg}{1791} -\glossaryentry{stoptoken.general@ {\memgloterm{stoptoken.general}}{\memglodesc{(\ref {stoptoken.general})}} {\memgloref{}}|memjustarg}{1791} -\glossaryentry{stoptoken.cons@ {\memgloterm{stoptoken.cons}}{\memglodesc{(\ref {stoptoken.cons})}} {\memgloref{}}|memjustarg}{1791} -\glossaryentry{stoptoken.mem@ {\memgloterm{stoptoken.mem}}{\memglodesc{(\ref {stoptoken.mem})}} {\memgloref{}}|memjustarg}{1792} -\glossaryentry{stoptoken.nonmembers@ {\memgloterm{stoptoken.nonmembers}}{\memglodesc{(\ref {stoptoken.nonmembers})}} {\memgloref{}}|memjustarg}{1792} -\glossaryentry{stopsource@ {\memgloterm{stopsource}}{\memglodesc{(\ref {stopsource})}} {\memgloref{}}|memjustarg}{1792} -\glossaryentry{stopsource.general@ {\memgloterm{stopsource.general}}{\memglodesc{(\ref {stopsource.general})}} {\memgloref{}}|memjustarg}{1792} -\glossaryentry{stopsource.cons@ {\memgloterm{stopsource.cons}}{\memglodesc{(\ref {stopsource.cons})}} {\memgloref{}}|memjustarg}{1793} -\glossaryentry{stopsource.mem@ {\memgloterm{stopsource.mem}}{\memglodesc{(\ref {stopsource.mem})}} {\memgloref{}}|memjustarg}{1794} -\glossaryentry{stopsource.nonmembers@ {\memgloterm{stopsource.nonmembers}}{\memglodesc{(\ref {stopsource.nonmembers})}} {\memgloref{}}|memjustarg}{1794} -\glossaryentry{stopcallback@ {\memgloterm{stopcallback}}{\memglodesc{(\ref {stopcallback})}} {\memgloref{}}|memjustarg}{1794} -\glossaryentry{stopcallback.general@ {\memgloterm{stopcallback.general}}{\memglodesc{(\ref {stopcallback.general})}} {\memgloref{}}|memjustarg}{1794} -\glossaryentry{stopcallback.cons@ {\memgloterm{stopcallback.cons}}{\memglodesc{(\ref {stopcallback.cons})}} {\memgloref{}}|memjustarg}{1795} -\glossaryentry{thread.threads@ {\memgloterm{thread.threads}}{\memglodesc{(\ref {thread.threads})}} {\memgloref{}}|memjustarg}{1795} -\glossaryentry{thread.threads.general@ {\memgloterm{thread.threads.general}}{\memglodesc{(\ref {thread.threads.general})}} {\memgloref{}}|memjustarg}{1795} -\glossaryentry{thread.syn@ {\memgloterm{thread.syn}}{\memglodesc{(\ref {thread.syn})}} {\memgloref{}}|memjustarg}{1795} -\glossaryentry{thread.thread.class@ {\memgloterm{thread.thread.class}}{\memglodesc{(\ref {thread.thread.class})}} {\memgloref{}}|memjustarg}{1796} -\glossaryentry{thread.thread.class.general@ {\memgloterm{thread.thread.class.general}}{\memglodesc{(\ref {thread.thread.class.general})}} {\memgloref{}}|memjustarg}{1796} -\glossaryentry{thread.thread.id@ {\memgloterm{thread.thread.id}}{\memglodesc{(\ref {thread.thread.id})}} {\memgloref{}}|memjustarg}{1796} -\glossaryentry{thread.thread.constr@ {\memgloterm{thread.thread.constr}}{\memglodesc{(\ref {thread.thread.constr})}} {\memgloref{}}|memjustarg}{1797} -\glossaryentry{thread.thread.destr@ {\memgloterm{thread.thread.destr}}{\memglodesc{(\ref {thread.thread.destr})}} {\memgloref{}}|memjustarg}{1798} -\glossaryentry{thread.thread.assign@ {\memgloterm{thread.thread.assign}}{\memglodesc{(\ref {thread.thread.assign})}} {\memgloref{}}|memjustarg}{1798} -\glossaryentry{thread.thread.member@ {\memgloterm{thread.thread.member}}{\memglodesc{(\ref {thread.thread.member})}} {\memgloref{}}|memjustarg}{1798} -\glossaryentry{thread.thread.static@ {\memgloterm{thread.thread.static}}{\memglodesc{(\ref {thread.thread.static})}} {\memgloref{}}|memjustarg}{1799} -\glossaryentry{thread.thread.algorithm@ {\memgloterm{thread.thread.algorithm}}{\memglodesc{(\ref {thread.thread.algorithm})}} {\memgloref{}}|memjustarg}{1799} -\glossaryentry{thread.jthread.class@ {\memgloterm{thread.jthread.class}}{\memglodesc{(\ref {thread.jthread.class})}} {\memgloref{}}|memjustarg}{1799} -\glossaryentry{thread.jthread.class.general@ {\memgloterm{thread.jthread.class.general}}{\memglodesc{(\ref {thread.jthread.class.general})}} {\memgloref{}}|memjustarg}{1799} -\glossaryentry{thread.jthread.cons@ {\memgloterm{thread.jthread.cons}}{\memglodesc{(\ref {thread.jthread.cons})}} {\memgloref{}}|memjustarg}{1800} -\glossaryentry{thread.jthread.mem@ {\memgloterm{thread.jthread.mem}}{\memglodesc{(\ref {thread.jthread.mem})}} {\memgloref{}}|memjustarg}{1801} -\glossaryentry{thread.jthread.stop@ {\memgloterm{thread.jthread.stop}}{\memglodesc{(\ref {thread.jthread.stop})}} {\memgloref{}}|memjustarg}{1802} -\glossaryentry{thread.jthread.special@ {\memgloterm{thread.jthread.special}}{\memglodesc{(\ref {thread.jthread.special})}} {\memgloref{}}|memjustarg}{1802} -\glossaryentry{thread.jthread.static@ {\memgloterm{thread.jthread.static}}{\memglodesc{(\ref {thread.jthread.static})}} {\memgloref{}}|memjustarg}{1802} -\glossaryentry{thread.thread.this@ {\memgloterm{thread.thread.this}}{\memglodesc{(\ref {thread.thread.this})}} {\memgloref{}}|memjustarg}{1802} -\glossaryentry{atomics@ {\memgloterm{atomics}}{\memglodesc{(\ref {atomics})}} {\memgloref{}}|memjustarg}{1803} -\glossaryentry{atomics.general@ {\memgloterm{atomics.general}}{\memglodesc{(\ref {atomics.general})}} {\memgloref{}}|memjustarg}{1803} -\glossaryentry{atomics.syn@ {\memgloterm{atomics.syn}}{\memglodesc{(\ref {atomics.syn})}} {\memgloref{}}|memjustarg}{1803} -\glossaryentry{atomics.alias@ {\memgloterm{atomics.alias}}{\memglodesc{(\ref {atomics.alias})}} {\memgloref{}}|memjustarg}{1807} -\glossaryentry{atomics.order@ {\memgloterm{atomics.order}}{\memglodesc{(\ref {atomics.order})}} {\memgloref{}}|memjustarg}{1807} -\glossaryentry{atomics.lockfree@ {\memgloterm{atomics.lockfree}}{\memglodesc{(\ref {atomics.lockfree})}} {\memgloref{}}|memjustarg}{1809} -\glossaryentry{atomics.wait@ {\memgloterm{atomics.wait}}{\memglodesc{(\ref {atomics.wait})}} {\memgloref{}}|memjustarg}{1809} -\glossaryentry{atomics.ref.generic@ {\memgloterm{atomics.ref.generic}}{\memglodesc{(\ref {atomics.ref.generic})}} {\memgloref{}}|memjustarg}{1810} -\glossaryentry{atomics.ref.generic.general@ {\memgloterm{atomics.ref.generic.general}}{\memglodesc{(\ref {atomics.ref.generic.general})}} {\memgloref{}}|memjustarg}{1810} -\glossaryentry{atomics.ref.ops@ {\memgloterm{atomics.ref.ops}}{\memglodesc{(\ref {atomics.ref.ops})}} {\memgloref{}}|memjustarg}{1811} -\glossaryentry{atomics.ref.int@ {\memgloterm{atomics.ref.int}}{\memglodesc{(\ref {atomics.ref.int})}} {\memgloref{}}|memjustarg}{1813} -\glossaryentry{atomics.ref.float@ {\memgloterm{atomics.ref.float}}{\memglodesc{(\ref {atomics.ref.float})}} {\memgloref{}}|memjustarg}{1814} -\glossaryentry{atomics.ref.pointer@ {\memgloterm{atomics.ref.pointer}}{\memglodesc{(\ref {atomics.ref.pointer})}} {\memgloref{}}|memjustarg}{1815} -\glossaryentry{atomics.ref.memop@ {\memgloterm{atomics.ref.memop}}{\memglodesc{(\ref {atomics.ref.memop})}} {\memgloref{}}|memjustarg}{1816} -\glossaryentry{atomics.types.generic@ {\memgloterm{atomics.types.generic}}{\memglodesc{(\ref {atomics.types.generic})}} {\memgloref{}}|memjustarg}{1816} -\glossaryentry{atomics.types.generic.general@ {\memgloterm{atomics.types.generic.general}}{\memglodesc{(\ref {atomics.types.generic.general})}} {\memgloref{}}|memjustarg}{1816} -\glossaryentry{atomics.types.operations@ {\memgloterm{atomics.types.operations}}{\memglodesc{(\ref {atomics.types.operations})}} {\memgloref{}}|memjustarg}{1817} -\glossaryentry{atomics.types.int@ {\memgloterm{atomics.types.int}}{\memglodesc{(\ref {atomics.types.int})}} {\memgloref{}}|memjustarg}{1821} -\glossaryentry{atomics.types.float@ {\memgloterm{atomics.types.float}}{\memglodesc{(\ref {atomics.types.float})}} {\memgloref{}}|memjustarg}{1823} -\glossaryentry{atomics.types.pointer@ {\memgloterm{atomics.types.pointer}}{\memglodesc{(\ref {atomics.types.pointer})}} {\memgloref{}}|memjustarg}{1825} -\glossaryentry{atomics.types.memop@ {\memgloterm{atomics.types.memop}}{\memglodesc{(\ref {atomics.types.memop})}} {\memgloref{}}|memjustarg}{1826} -\glossaryentry{util.smartptr.atomic@ {\memgloterm{util.smartptr.atomic}}{\memglodesc{(\ref {util.smartptr.atomic})}} {\memgloref{}}|memjustarg}{1827} -\glossaryentry{util.smartptr.atomic.general@ {\memgloterm{util.smartptr.atomic.general}}{\memglodesc{(\ref {util.smartptr.atomic.general})}} {\memgloref{}}|memjustarg}{1827} -\glossaryentry{util.smartptr.atomic.shared@ {\memgloterm{util.smartptr.atomic.shared}}{\memglodesc{(\ref {util.smartptr.atomic.shared})}} {\memgloref{}}|memjustarg}{1827} -\glossaryentry{util.smartptr.atomic.weak@ {\memgloterm{util.smartptr.atomic.weak}}{\memglodesc{(\ref {util.smartptr.atomic.weak})}} {\memgloref{}}|memjustarg}{1829} -\glossaryentry{atomics.nonmembers@ {\memgloterm{atomics.nonmembers}}{\memglodesc{(\ref {atomics.nonmembers})}} {\memgloref{}}|memjustarg}{1832} -\glossaryentry{atomics.flag@ {\memgloterm{atomics.flag}}{\memglodesc{(\ref {atomics.flag})}} {\memgloref{}}|memjustarg}{1832} -\glossaryentry{atomics.fences@ {\memgloterm{atomics.fences}}{\memglodesc{(\ref {atomics.fences})}} {\memgloref{}}|memjustarg}{1834} -\glossaryentry{stdatomic.h.syn@ {\memgloterm{stdatomic.h.syn}}{\memglodesc{(\ref {stdatomic.h.syn})}} {\memgloref{}}|memjustarg}{1834} -\glossaryentry{thread.mutex@ {\memgloterm{thread.mutex}}{\memglodesc{(\ref {thread.mutex})}} {\memgloref{}}|memjustarg}{1836} -\glossaryentry{thread.mutex.general@ {\memgloterm{thread.mutex.general}}{\memglodesc{(\ref {thread.mutex.general})}} {\memgloref{}}|memjustarg}{1836} -\glossaryentry{mutex.syn@ {\memgloterm{mutex.syn}}{\memglodesc{(\ref {mutex.syn})}} {\memgloref{}}|memjustarg}{1836} -\glossaryentry{shared.mutex.syn@ {\memgloterm{shared.mutex.syn}}{\memglodesc{(\ref {shared.mutex.syn})}} {\memgloref{}}|memjustarg}{1837} -\glossaryentry{thread.mutex.requirements@ {\memgloterm{thread.mutex.requirements}}{\memglodesc{(\ref {thread.mutex.requirements})}} {\memgloref{}}|memjustarg}{1837} -\glossaryentry{thread.mutex.requirements.general@ {\memgloterm{thread.mutex.requirements.general}}{\memglodesc{(\ref {thread.mutex.requirements.general})}} {\memgloref{}}|memjustarg}{1837} -\glossaryentry{thread.mutex.requirements.mutex@ {\memgloterm{thread.mutex.requirements.mutex}}{\memglodesc{(\ref {thread.mutex.requirements.mutex})}} {\memgloref{}}|memjustarg}{1837} -\glossaryentry{thread.mutex.requirements.mutex.general@ {\memgloterm{thread.mutex.requirements.mutex.general}}{\memglodesc{(\ref {thread.mutex.requirements.mutex.general})}} {\memgloref{}}|memjustarg}{1837} -\glossaryentry{thread.mutex.class@ {\memgloterm{thread.mutex.class}}{\memglodesc{(\ref {thread.mutex.class})}} {\memgloref{}}|memjustarg}{1838} -\glossaryentry{thread.mutex.recursive@ {\memgloterm{thread.mutex.recursive}}{\memglodesc{(\ref {thread.mutex.recursive})}} {\memgloref{}}|memjustarg}{1839} -\glossaryentry{thread.timedmutex.requirements@ {\memgloterm{thread.timedmutex.requirements}}{\memglodesc{(\ref {thread.timedmutex.requirements})}} {\memgloref{}}|memjustarg}{1839} -\glossaryentry{thread.timedmutex.requirements.general@ {\memgloterm{thread.timedmutex.requirements.general}}{\memglodesc{(\ref {thread.timedmutex.requirements.general})}} {\memgloref{}}|memjustarg}{1839} -\glossaryentry{thread.timedmutex.class@ {\memgloterm{thread.timedmutex.class}}{\memglodesc{(\ref {thread.timedmutex.class})}} {\memgloref{}}|memjustarg}{1840} -\glossaryentry{thread.timedmutex.recursive@ {\memgloterm{thread.timedmutex.recursive}}{\memglodesc{(\ref {thread.timedmutex.recursive})}} {\memgloref{}}|memjustarg}{1841} -\glossaryentry{thread.sharedmutex.requirements@ {\memgloterm{thread.sharedmutex.requirements}}{\memglodesc{(\ref {thread.sharedmutex.requirements})}} {\memgloref{}}|memjustarg}{1841} -\glossaryentry{thread.sharedmutex.requirements.general@ {\memgloterm{thread.sharedmutex.requirements.general}}{\memglodesc{(\ref {thread.sharedmutex.requirements.general})}} {\memgloref{}}|memjustarg}{1841} -\glossaryentry{thread.sharedmutex.class@ {\memgloterm{thread.sharedmutex.class}}{\memglodesc{(\ref {thread.sharedmutex.class})}} {\memgloref{}}|memjustarg}{1842} -\glossaryentry{thread.sharedtimedmutex.requirements@ {\memgloterm{thread.sharedtimedmutex.requirements}}{\memglodesc{(\ref {thread.sharedtimedmutex.requirements})}} {\memgloref{}}|memjustarg}{1843} -\glossaryentry{thread.sharedtimedmutex.requirements.general@ {\memgloterm{thread.sharedtimedmutex.requirements.general}}{\memglodesc{(\ref {thread.sharedtimedmutex.requirements.general})}} {\memgloref{}}|memjustarg}{1843} -\glossaryentry{thread.sharedtimedmutex.class@ {\memgloterm{thread.sharedtimedmutex.class}}{\memglodesc{(\ref {thread.sharedtimedmutex.class})}} {\memgloref{}}|memjustarg}{1844} -\glossaryentry{thread.lock@ {\memgloterm{thread.lock}}{\memglodesc{(\ref {thread.lock})}} {\memgloref{}}|memjustarg}{1844} -\glossaryentry{thread.lock.general@ {\memgloterm{thread.lock.general}}{\memglodesc{(\ref {thread.lock.general})}} {\memgloref{}}|memjustarg}{1844} -\glossaryentry{thread.lock.guard@ {\memgloterm{thread.lock.guard}}{\memglodesc{(\ref {thread.lock.guard})}} {\memgloref{}}|memjustarg}{1845} -\glossaryentry{thread.lock.scoped@ {\memgloterm{thread.lock.scoped}}{\memglodesc{(\ref {thread.lock.scoped})}} {\memgloref{}}|memjustarg}{1845} -\glossaryentry{thread.lock.unique@ {\memgloterm{thread.lock.unique}}{\memglodesc{(\ref {thread.lock.unique})}} {\memgloref{}}|memjustarg}{1846} -\glossaryentry{thread.lock.unique.general@ {\memgloterm{thread.lock.unique.general}}{\memglodesc{(\ref {thread.lock.unique.general})}} {\memgloref{}}|memjustarg}{1846} -\glossaryentry{thread.lock.unique.cons@ {\memgloterm{thread.lock.unique.cons}}{\memglodesc{(\ref {thread.lock.unique.cons})}} {\memgloref{}}|memjustarg}{1847} -\glossaryentry{thread.lock.unique.locking@ {\memgloterm{thread.lock.unique.locking}}{\memglodesc{(\ref {thread.lock.unique.locking})}} {\memgloref{}}|memjustarg}{1848} -\glossaryentry{thread.lock.unique.mod@ {\memgloterm{thread.lock.unique.mod}}{\memglodesc{(\ref {thread.lock.unique.mod})}} {\memgloref{}}|memjustarg}{1849} -\glossaryentry{thread.lock.unique.obs@ {\memgloterm{thread.lock.unique.obs}}{\memglodesc{(\ref {thread.lock.unique.obs})}} {\memgloref{}}|memjustarg}{1849} -\glossaryentry{thread.lock.shared@ {\memgloterm{thread.lock.shared}}{\memglodesc{(\ref {thread.lock.shared})}} {\memgloref{}}|memjustarg}{1849} -\glossaryentry{thread.lock.shared.general@ {\memgloterm{thread.lock.shared.general}}{\memglodesc{(\ref {thread.lock.shared.general})}} {\memgloref{}}|memjustarg}{1849} -\glossaryentry{thread.lock.shared.cons@ {\memgloterm{thread.lock.shared.cons}}{\memglodesc{(\ref {thread.lock.shared.cons})}} {\memgloref{}}|memjustarg}{1850} -\glossaryentry{thread.lock.shared.locking@ {\memgloterm{thread.lock.shared.locking}}{\memglodesc{(\ref {thread.lock.shared.locking})}} {\memgloref{}}|memjustarg}{1851} -\glossaryentry{thread.lock.shared.mod@ {\memgloterm{thread.lock.shared.mod}}{\memglodesc{(\ref {thread.lock.shared.mod})}} {\memgloref{}}|memjustarg}{1852} -\glossaryentry{thread.lock.shared.obs@ {\memgloterm{thread.lock.shared.obs}}{\memglodesc{(\ref {thread.lock.shared.obs})}} {\memgloref{}}|memjustarg}{1853} -\glossaryentry{thread.lock.algorithm@ {\memgloterm{thread.lock.algorithm}}{\memglodesc{(\ref {thread.lock.algorithm})}} {\memgloref{}}|memjustarg}{1853} -\glossaryentry{thread.once@ {\memgloterm{thread.once}}{\memglodesc{(\ref {thread.once})}} {\memgloref{}}|memjustarg}{1853} -\glossaryentry{thread.once.onceflag@ {\memgloterm{thread.once.onceflag}}{\memglodesc{(\ref {thread.once.onceflag})}} {\memgloref{}}|memjustarg}{1853} -\glossaryentry{thread.once.callonce@ {\memgloterm{thread.once.callonce}}{\memglodesc{(\ref {thread.once.callonce})}} {\memgloref{}}|memjustarg}{1854} -\glossaryentry{thread.condition@ {\memgloterm{thread.condition}}{\memglodesc{(\ref {thread.condition})}} {\memgloref{}}|memjustarg}{1854} -\glossaryentry{thread.condition.general@ {\memgloterm{thread.condition.general}}{\memglodesc{(\ref {thread.condition.general})}} {\memgloref{}}|memjustarg}{1854} -\glossaryentry{condition.variable.syn@ {\memgloterm{condition.variable.syn}}{\memglodesc{(\ref {condition.variable.syn})}} {\memgloref{}}|memjustarg}{1855} -\glossaryentry{thread.condition.nonmember@ {\memgloterm{thread.condition.nonmember}}{\memglodesc{(\ref {thread.condition.nonmember})}} {\memgloref{}}|memjustarg}{1855} -\glossaryentry{thread.condition.condvar@ {\memgloterm{thread.condition.condvar}}{\memglodesc{(\ref {thread.condition.condvar})}} {\memgloref{}}|memjustarg}{1855} -\glossaryentry{thread.condition.condvarany@ {\memgloterm{thread.condition.condvarany}}{\memglodesc{(\ref {thread.condition.condvarany})}} {\memgloref{}}|memjustarg}{1858} -\glossaryentry{thread.condition.condvarany.general@ {\memgloterm{thread.condition.condvarany.general}}{\memglodesc{(\ref {thread.condition.condvarany.general})}} {\memgloref{}}|memjustarg}{1858} -\glossaryentry{thread.condvarany.wait@ {\memgloterm{thread.condvarany.wait}}{\memglodesc{(\ref {thread.condvarany.wait})}} {\memgloref{}}|memjustarg}{1859} -\glossaryentry{thread.condvarany.intwait@ {\memgloterm{thread.condvarany.intwait}}{\memglodesc{(\ref {thread.condvarany.intwait})}} {\memgloref{}}|memjustarg}{1861} -\glossaryentry{thread.sema@ {\memgloterm{thread.sema}}{\memglodesc{(\ref {thread.sema})}} {\memgloref{}}|memjustarg}{1862} -\glossaryentry{thread.sema.general@ {\memgloterm{thread.sema.general}}{\memglodesc{(\ref {thread.sema.general})}} {\memgloref{}}|memjustarg}{1862} -\glossaryentry{semaphore.syn@ {\memgloterm{semaphore.syn}}{\memglodesc{(\ref {semaphore.syn})}} {\memgloref{}}|memjustarg}{1862} -\glossaryentry{thread.sema.cnt@ {\memgloterm{thread.sema.cnt}}{\memglodesc{(\ref {thread.sema.cnt})}} {\memgloref{}}|memjustarg}{1862} -\glossaryentry{thread.coord@ {\memgloterm{thread.coord}}{\memglodesc{(\ref {thread.coord})}} {\memgloref{}}|memjustarg}{1863} -\glossaryentry{thread.coord.general@ {\memgloterm{thread.coord.general}}{\memglodesc{(\ref {thread.coord.general})}} {\memgloref{}}|memjustarg}{1863} -\glossaryentry{thread.latch@ {\memgloterm{thread.latch}}{\memglodesc{(\ref {thread.latch})}} {\memgloref{}}|memjustarg}{1863} -\glossaryentry{thread.latch.general@ {\memgloterm{thread.latch.general}}{\memglodesc{(\ref {thread.latch.general})}} {\memgloref{}}|memjustarg}{1863} -\glossaryentry{latch.syn@ {\memgloterm{latch.syn}}{\memglodesc{(\ref {latch.syn})}} {\memgloref{}}|memjustarg}{1864} -\glossaryentry{thread.latch.class@ {\memgloterm{thread.latch.class}}{\memglodesc{(\ref {thread.latch.class})}} {\memgloref{}}|memjustarg}{1864} -\glossaryentry{thread.barrier@ {\memgloterm{thread.barrier}}{\memglodesc{(\ref {thread.barrier})}} {\memgloref{}}|memjustarg}{1865} -\glossaryentry{thread.barrier.general@ {\memgloterm{thread.barrier.general}}{\memglodesc{(\ref {thread.barrier.general})}} {\memgloref{}}|memjustarg}{1865} -\glossaryentry{barrier.syn@ {\memgloterm{barrier.syn}}{\memglodesc{(\ref {barrier.syn})}} {\memgloref{}}|memjustarg}{1865} -\glossaryentry{thread.barrier.class@ {\memgloterm{thread.barrier.class}}{\memglodesc{(\ref {thread.barrier.class})}} {\memgloref{}}|memjustarg}{1865} -\glossaryentry{futures@ {\memgloterm{futures}}{\memglodesc{(\ref {futures})}} {\memgloref{}}|memjustarg}{1867} -\glossaryentry{futures.overview@ {\memgloterm{futures.overview}}{\memglodesc{(\ref {futures.overview})}} {\memgloref{}}|memjustarg}{1867} -\glossaryentry{future.syn@ {\memgloterm{future.syn}}{\memglodesc{(\ref {future.syn})}} {\memgloref{}}|memjustarg}{1867} -\glossaryentry{futures.errors@ {\memgloterm{futures.errors}}{\memglodesc{(\ref {futures.errors})}} {\memgloref{}}|memjustarg}{1868} -\glossaryentry{futures.future.error@ {\memgloterm{futures.future.error}}{\memglodesc{(\ref {futures.future.error})}} {\memgloref{}}|memjustarg}{1868} -\glossaryentry{futures.state@ {\memgloterm{futures.state}}{\memglodesc{(\ref {futures.state})}} {\memgloref{}}|memjustarg}{1869} -\glossaryentry{futures.promise@ {\memgloterm{futures.promise}}{\memglodesc{(\ref {futures.promise})}} {\memgloref{}}|memjustarg}{1870} -\glossaryentry{futures.unique.future@ {\memgloterm{futures.unique.future}}{\memglodesc{(\ref {futures.unique.future})}} {\memgloref{}}|memjustarg}{1872} -\glossaryentry{futures.shared.future@ {\memgloterm{futures.shared.future}}{\memglodesc{(\ref {futures.shared.future})}} {\memgloref{}}|memjustarg}{1874} -\glossaryentry{futures.async@ {\memgloterm{futures.async}}{\memglodesc{(\ref {futures.async})}} {\memgloref{}}|memjustarg}{1877} -\glossaryentry{futures.task@ {\memgloterm{futures.task}}{\memglodesc{(\ref {futures.task})}} {\memgloref{}}|memjustarg}{1878} -\glossaryentry{futures.task.general@ {\memgloterm{futures.task.general}}{\memglodesc{(\ref {futures.task.general})}} {\memgloref{}}|memjustarg}{1878} -\glossaryentry{futures.task.members@ {\memgloterm{futures.task.members}}{\memglodesc{(\ref {futures.task.members})}} {\memgloref{}}|memjustarg}{1879} -\glossaryentry{futures.task.nonmembers@ {\memgloterm{futures.task.nonmembers}}{\memglodesc{(\ref {futures.task.nonmembers})}} {\memgloref{}}|memjustarg}{1880} -\glossaryentry{gram@ {\memgloterm{gram}}{\memglodesc{(\ref {gram})}} {\memgloref{}}|memjustarg}{1881} -\glossaryentry{gram.general@ {\memgloterm{gram.general}}{\memglodesc{(\ref {gram.general})}} {\memgloref{}}|memjustarg}{1881} -\glossaryentry{gram.key@ {\memgloterm{gram.key}}{\memglodesc{(\ref {gram.key})}} {\memgloref{}}|memjustarg}{1881} -\glossaryentry{gram.lex@ {\memgloterm{gram.lex}}{\memglodesc{(\ref {gram.lex})}} {\memgloref{}}|memjustarg}{1881} -\glossaryentry{gram.basic@ {\memgloterm{gram.basic}}{\memglodesc{(\ref {gram.basic})}} {\memgloref{}}|memjustarg}{1886} -\glossaryentry{gram.expr@ {\memgloterm{gram.expr}}{\memglodesc{(\ref {gram.expr})}} {\memgloref{}}|memjustarg}{1886} -\glossaryentry{gram.stmt@ {\memgloterm{gram.stmt}}{\memglodesc{(\ref {gram.stmt})}} {\memgloref{}}|memjustarg}{1890} -\glossaryentry{gram.dcl@ {\memgloterm{gram.dcl}}{\memglodesc{(\ref {gram.dcl})}} {\memgloref{}}|memjustarg}{1891} -\glossaryentry{gram.module@ {\memgloterm{gram.module}}{\memglodesc{(\ref {gram.module})}} {\memgloref{}}|memjustarg}{1897} -\glossaryentry{gram.class@ {\memgloterm{gram.class}}{\memglodesc{(\ref {gram.class})}} {\memgloref{}}|memjustarg}{1898} -\glossaryentry{gram.over@ {\memgloterm{gram.over}}{\memglodesc{(\ref {gram.over})}} {\memgloref{}}|memjustarg}{1899} -\glossaryentry{gram.temp@ {\memgloterm{gram.temp}}{\memglodesc{(\ref {gram.temp})}} {\memgloref{}}|memjustarg}{1899} -\glossaryentry{gram.except@ {\memgloterm{gram.except}}{\memglodesc{(\ref {gram.except})}} {\memgloref{}}|memjustarg}{1900} -\glossaryentry{gram.cpp@ {\memgloterm{gram.cpp}}{\memglodesc{(\ref {gram.cpp})}} {\memgloref{}}|memjustarg}{1901} -\glossaryentry{implimits@ {\memgloterm{implimits}}{\memglodesc{(\ref {implimits})}} {\memgloref{}}|memjustarg}{1903} -\glossaryentry{diff@ {\memgloterm{diff}}{\memglodesc{(\ref {diff})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20@ {\memgloterm{diff.cpp20}}{\memglodesc{(\ref {diff.cpp20})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20.general@ {\memgloterm{diff.cpp20.general}}{\memglodesc{(\ref {diff.cpp20.general})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20.lex@ {\memgloterm{diff.cpp20.lex}}{\memglodesc{(\ref {diff.cpp20.lex})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20.expr@ {\memgloterm{diff.cpp20.expr}}{\memglodesc{(\ref {diff.cpp20.expr})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20.stmt@ {\memgloterm{diff.cpp20.stmt}}{\memglodesc{(\ref {diff.cpp20.stmt})}} {\memgloref{}}|memjustarg}{1905} -\glossaryentry{diff.cpp20.dcl@ {\memgloterm{diff.cpp20.dcl}}{\memglodesc{(\ref {diff.cpp20.dcl})}} {\memgloref{}}|memjustarg}{1906} -\glossaryentry{diff.cpp20.temp@ {\memgloterm{diff.cpp20.temp}}{\memglodesc{(\ref {diff.cpp20.temp})}} {\memgloref{}}|memjustarg}{1906} -\glossaryentry{diff.cpp20.library@ {\memgloterm{diff.cpp20.library}}{\memglodesc{(\ref {diff.cpp20.library})}} {\memgloref{}}|memjustarg}{1906} -\glossaryentry{diff.cpp20.concepts@ {\memgloterm{diff.cpp20.concepts}}{\memglodesc{(\ref {diff.cpp20.concepts})}} {\memgloref{}}|memjustarg}{1906} -\glossaryentry{diff.cpp20.memory@ {\memgloterm{diff.cpp20.memory}}{\memglodesc{(\ref {diff.cpp20.memory})}} {\memgloref{}}|memjustarg}{1907} -\glossaryentry{diff.cpp20.utilities@ {\memgloterm{diff.cpp20.utilities}}{\memglodesc{(\ref {diff.cpp20.utilities})}} {\memgloref{}}|memjustarg}{1907} -\glossaryentry{diff.cpp20.strings@ {\memgloterm{diff.cpp20.strings}}{\memglodesc{(\ref {diff.cpp20.strings})}} {\memgloref{}}|memjustarg}{1907} -\glossaryentry{diff.cpp20.containers@ {\memgloterm{diff.cpp20.containers}}{\memglodesc{(\ref {diff.cpp20.containers})}} {\memgloref{}}|memjustarg}{1908} -\glossaryentry{diff.cpp20.thread@ {\memgloterm{diff.cpp20.thread}}{\memglodesc{(\ref {diff.cpp20.thread})}} {\memgloref{}}|memjustarg}{1908} -\glossaryentry{diff.cpp17@ {\memgloterm{diff.cpp17}}{\memglodesc{(\ref {diff.cpp17})}} {\memgloref{}}|memjustarg}{1908} -\glossaryentry{diff.cpp17.general@ {\memgloterm{diff.cpp17.general}}{\memglodesc{(\ref {diff.cpp17.general})}} {\memgloref{}}|memjustarg}{1908} -\glossaryentry{diff.cpp17.lex@ {\memgloterm{diff.cpp17.lex}}{\memglodesc{(\ref {diff.cpp17.lex})}} {\memgloref{}}|memjustarg}{1908} -\glossaryentry{diff.cpp17.basic@ {\memgloterm{diff.cpp17.basic}}{\memglodesc{(\ref {diff.cpp17.basic})}} {\memgloref{}}|memjustarg}{1910} -\glossaryentry{diff.cpp17.expr@ {\memgloterm{diff.cpp17.expr}}{\memglodesc{(\ref {diff.cpp17.expr})}} {\memgloref{}}|memjustarg}{1910} -\glossaryentry{diff.cpp17.dcl.dcl@ {\memgloterm{diff.cpp17.dcl.dcl}}{\memglodesc{(\ref {diff.cpp17.dcl.dcl})}} {\memgloref{}}|memjustarg}{1910} -\glossaryentry{diff.cpp17.class@ {\memgloterm{diff.cpp17.class}}{\memglodesc{(\ref {diff.cpp17.class})}} {\memgloref{}}|memjustarg}{1911} -\glossaryentry{diff.cpp17.over@ {\memgloterm{diff.cpp17.over}}{\memglodesc{(\ref {diff.cpp17.over})}} {\memgloref{}}|memjustarg}{1912} -\glossaryentry{diff.cpp17.temp@ {\memgloterm{diff.cpp17.temp}}{\memglodesc{(\ref {diff.cpp17.temp})}} {\memgloref{}}|memjustarg}{1913} -\glossaryentry{diff.cpp17.except@ {\memgloterm{diff.cpp17.except}}{\memglodesc{(\ref {diff.cpp17.except})}} {\memgloref{}}|memjustarg}{1913} -\glossaryentry{diff.cpp17.library@ {\memgloterm{diff.cpp17.library}}{\memglodesc{(\ref {diff.cpp17.library})}} {\memgloref{}}|memjustarg}{1913} -\glossaryentry{diff.cpp17.containers@ {\memgloterm{diff.cpp17.containers}}{\memglodesc{(\ref {diff.cpp17.containers})}} {\memgloref{}}|memjustarg}{1914} -\glossaryentry{diff.cpp17.iterators@ {\memgloterm{diff.cpp17.iterators}}{\memglodesc{(\ref {diff.cpp17.iterators})}} {\memgloref{}}|memjustarg}{1914} -\glossaryentry{diff.cpp17.alg.reqs@ {\memgloterm{diff.cpp17.alg.reqs}}{\memglodesc{(\ref {diff.cpp17.alg.reqs})}} {\memgloref{}}|memjustarg}{1914} -\glossaryentry{diff.cpp17.input.output@ {\memgloterm{diff.cpp17.input.output}}{\memglodesc{(\ref {diff.cpp17.input.output})}} {\memgloref{}}|memjustarg}{1914} -\glossaryentry{diff.cpp17.depr@ {\memgloterm{diff.cpp17.depr}}{\memglodesc{(\ref {diff.cpp17.depr})}} {\memgloref{}}|memjustarg}{1915} -\glossaryentry{diff.cpp14@ {\memgloterm{diff.cpp14}}{\memglodesc{(\ref {diff.cpp14})}} {\memgloref{}}|memjustarg}{1916} -\glossaryentry{diff.cpp14.general@ {\memgloterm{diff.cpp14.general}}{\memglodesc{(\ref {diff.cpp14.general})}} {\memgloref{}}|memjustarg}{1916} -\glossaryentry{diff.cpp14.lex@ {\memgloterm{diff.cpp14.lex}}{\memglodesc{(\ref {diff.cpp14.lex})}} {\memgloref{}}|memjustarg}{1916} -\glossaryentry{diff.cpp14.expr@ {\memgloterm{diff.cpp14.expr}}{\memglodesc{(\ref {diff.cpp14.expr})}} {\memgloref{}}|memjustarg}{1916} -\glossaryentry{diff.cpp14.dcl.dcl@ {\memgloterm{diff.cpp14.dcl.dcl}}{\memglodesc{(\ref {diff.cpp14.dcl.dcl})}} {\memgloref{}}|memjustarg}{1916} -\glossaryentry{diff.cpp14.class@ {\memgloterm{diff.cpp14.class}}{\memglodesc{(\ref {diff.cpp14.class})}} {\memgloref{}}|memjustarg}{1917} -\glossaryentry{diff.cpp14.temp@ {\memgloterm{diff.cpp14.temp}}{\memglodesc{(\ref {diff.cpp14.temp})}} {\memgloref{}}|memjustarg}{1917} -\glossaryentry{diff.cpp14.except@ {\memgloterm{diff.cpp14.except}}{\memglodesc{(\ref {diff.cpp14.except})}} {\memgloref{}}|memjustarg}{1918} -\glossaryentry{diff.cpp14.library@ {\memgloterm{diff.cpp14.library}}{\memglodesc{(\ref {diff.cpp14.library})}} {\memgloref{}}|memjustarg}{1918} -\glossaryentry{diff.cpp14.utilities@ {\memgloterm{diff.cpp14.utilities}}{\memglodesc{(\ref {diff.cpp14.utilities})}} {\memgloref{}}|memjustarg}{1918} -\glossaryentry{diff.cpp14.string@ {\memgloterm{diff.cpp14.string}}{\memglodesc{(\ref {diff.cpp14.string})}} {\memgloref{}}|memjustarg}{1918} -\glossaryentry{diff.cpp14.containers@ {\memgloterm{diff.cpp14.containers}}{\memglodesc{(\ref {diff.cpp14.containers})}} {\memgloref{}}|memjustarg}{1919} -\glossaryentry{diff.cpp14.depr@ {\memgloterm{diff.cpp14.depr}}{\memglodesc{(\ref {diff.cpp14.depr})}} {\memgloref{}}|memjustarg}{1919} -\glossaryentry{diff.cpp11@ {\memgloterm{diff.cpp11}}{\memglodesc{(\ref {diff.cpp11})}} {\memgloref{}}|memjustarg}{1919} -\glossaryentry{diff.cpp11.general@ {\memgloterm{diff.cpp11.general}}{\memglodesc{(\ref {diff.cpp11.general})}} {\memgloref{}}|memjustarg}{1919} -\glossaryentry{diff.cpp11.lex@ {\memgloterm{diff.cpp11.lex}}{\memglodesc{(\ref {diff.cpp11.lex})}} {\memgloref{}}|memjustarg}{1919} -\glossaryentry{diff.cpp11.basic@ {\memgloterm{diff.cpp11.basic}}{\memglodesc{(\ref {diff.cpp11.basic})}} {\memgloref{}}|memjustarg}{1920} -\glossaryentry{diff.cpp11.expr@ {\memgloterm{diff.cpp11.expr}}{\memglodesc{(\ref {diff.cpp11.expr})}} {\memgloref{}}|memjustarg}{1920} -\glossaryentry{diff.cpp11.dcl.dcl@ {\memgloterm{diff.cpp11.dcl.dcl}}{\memglodesc{(\ref {diff.cpp11.dcl.dcl})}} {\memgloref{}}|memjustarg}{1920} -\glossaryentry{diff.cpp11.library@ {\memgloterm{diff.cpp11.library}}{\memglodesc{(\ref {diff.cpp11.library})}} {\memgloref{}}|memjustarg}{1921} -\glossaryentry{diff.cpp11.input.output@ {\memgloterm{diff.cpp11.input.output}}{\memglodesc{(\ref {diff.cpp11.input.output})}} {\memgloref{}}|memjustarg}{1921} -\glossaryentry{diff.cpp03@ {\memgloterm{diff.cpp03}}{\memglodesc{(\ref {diff.cpp03})}} {\memgloref{}}|memjustarg}{1921} -\glossaryentry{diff.cpp03.general@ {\memgloterm{diff.cpp03.general}}{\memglodesc{(\ref {diff.cpp03.general})}} {\memgloref{}}|memjustarg}{1921} -\glossaryentry{diff.cpp03.lex@ {\memgloterm{diff.cpp03.lex}}{\memglodesc{(\ref {diff.cpp03.lex})}} {\memgloref{}}|memjustarg}{1921} -\glossaryentry{diff.cpp03.expr@ {\memgloterm{diff.cpp03.expr}}{\memglodesc{(\ref {diff.cpp03.expr})}} {\memgloref{}}|memjustarg}{1922} -\glossaryentry{diff.cpp03.dcl.dcl@ {\memgloterm{diff.cpp03.dcl.dcl}}{\memglodesc{(\ref {diff.cpp03.dcl.dcl})}} {\memgloref{}}|memjustarg}{1922} -\glossaryentry{diff.cpp03.class@ {\memgloterm{diff.cpp03.class}}{\memglodesc{(\ref {diff.cpp03.class})}} {\memgloref{}}|memjustarg}{1922} -\glossaryentry{diff.cpp03.temp@ {\memgloterm{diff.cpp03.temp}}{\memglodesc{(\ref {diff.cpp03.temp})}} {\memgloref{}}|memjustarg}{1923} -\glossaryentry{diff.cpp03.library@ {\memgloterm{diff.cpp03.library}}{\memglodesc{(\ref {diff.cpp03.library})}} {\memgloref{}}|memjustarg}{1923} -\glossaryentry{diff.cpp03.language.support@ {\memgloterm{diff.cpp03.language.support}}{\memglodesc{(\ref {diff.cpp03.language.support})}} {\memgloref{}}|memjustarg}{1924} -\glossaryentry{diff.cpp03.diagnostics@ {\memgloterm{diff.cpp03.diagnostics}}{\memglodesc{(\ref {diff.cpp03.diagnostics})}} {\memgloref{}}|memjustarg}{1924} -\glossaryentry{diff.cpp03.utilities@ {\memgloterm{diff.cpp03.utilities}}{\memglodesc{(\ref {diff.cpp03.utilities})}} {\memgloref{}}|memjustarg}{1924} -\glossaryentry{diff.cpp03.strings@ {\memgloterm{diff.cpp03.strings}}{\memglodesc{(\ref {diff.cpp03.strings})}} {\memgloref{}}|memjustarg}{1924} -\glossaryentry{diff.cpp03.containers@ {\memgloterm{diff.cpp03.containers}}{\memglodesc{(\ref {diff.cpp03.containers})}} {\memgloref{}}|memjustarg}{1924} -\glossaryentry{diff.cpp03.algorithms@ {\memgloterm{diff.cpp03.algorithms}}{\memglodesc{(\ref {diff.cpp03.algorithms})}} {\memgloref{}}|memjustarg}{1925} -\glossaryentry{diff.cpp03.numerics@ {\memgloterm{diff.cpp03.numerics}}{\memglodesc{(\ref {diff.cpp03.numerics})}} {\memgloref{}}|memjustarg}{1925} -\glossaryentry{diff.cpp03.locale@ {\memgloterm{diff.cpp03.locale}}{\memglodesc{(\ref {diff.cpp03.locale})}} {\memgloref{}}|memjustarg}{1925} -\glossaryentry{diff.cpp03.input.output@ {\memgloterm{diff.cpp03.input.output}}{\memglodesc{(\ref {diff.cpp03.input.output})}} {\memgloref{}}|memjustarg}{1926} -\glossaryentry{diff.iso@ {\memgloterm{diff.iso}}{\memglodesc{(\ref {diff.iso})}} {\memgloref{}}|memjustarg}{1926} -\glossaryentry{diff.iso.general@ {\memgloterm{diff.iso.general}}{\memglodesc{(\ref {diff.iso.general})}} {\memgloref{}}|memjustarg}{1926} -\glossaryentry{diff.lex@ {\memgloterm{diff.lex}}{\memglodesc{(\ref {diff.lex})}} {\memgloref{}}|memjustarg}{1926} -\glossaryentry{diff.basic@ {\memgloterm{diff.basic}}{\memglodesc{(\ref {diff.basic})}} {\memgloref{}}|memjustarg}{1927} -\glossaryentry{diff.expr@ {\memgloterm{diff.expr}}{\memglodesc{(\ref {diff.expr})}} {\memgloref{}}|memjustarg}{1928} -\glossaryentry{diff.stat@ {\memgloterm{diff.stat}}{\memglodesc{(\ref {diff.stat})}} {\memgloref{}}|memjustarg}{1929} -\glossaryentry{diff.dcl@ {\memgloterm{diff.dcl}}{\memglodesc{(\ref {diff.dcl})}} {\memgloref{}}|memjustarg}{1929} -\glossaryentry{diff.class@ {\memgloterm{diff.class}}{\memglodesc{(\ref {diff.class})}} {\memgloref{}}|memjustarg}{1932} -\glossaryentry{diff.cpp@ {\memgloterm{diff.cpp}}{\memglodesc{(\ref {diff.cpp})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.library@ {\memgloterm{diff.library}}{\memglodesc{(\ref {diff.library})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.library.general@ {\memgloterm{diff.library.general}}{\memglodesc{(\ref {diff.library.general})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.mods.to.headers@ {\memgloterm{diff.mods.to.headers}}{\memglodesc{(\ref {diff.mods.to.headers})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.mods.to.definitions@ {\memgloterm{diff.mods.to.definitions}}{\memglodesc{(\ref {diff.mods.to.definitions})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.char16@ {\memgloterm{diff.char16}}{\memglodesc{(\ref {diff.char16})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.wchar.t@ {\memgloterm{diff.wchar.t}}{\memglodesc{(\ref {diff.wchar.t})}} {\memgloref{}}|memjustarg}{1934} -\glossaryentry{diff.header.assert.h@ {\memgloterm{diff.header.assert.h}}{\memglodesc{(\ref {diff.header.assert.h})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.header.iso646.h@ {\memgloterm{diff.header.iso646.h}}{\memglodesc{(\ref {diff.header.iso646.h})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.header.stdalign.h@ {\memgloterm{diff.header.stdalign.h}}{\memglodesc{(\ref {diff.header.stdalign.h})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.header.stdbool.h@ {\memgloterm{diff.header.stdbool.h}}{\memglodesc{(\ref {diff.header.stdbool.h})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.null@ {\memgloterm{diff.null}}{\memglodesc{(\ref {diff.null})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.mods.to.declarations@ {\memgloterm{diff.mods.to.declarations}}{\memglodesc{(\ref {diff.mods.to.declarations})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.mods.to.behavior@ {\memgloterm{diff.mods.to.behavior}}{\memglodesc{(\ref {diff.mods.to.behavior})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.mods.to.behavior.general@ {\memgloterm{diff.mods.to.behavior.general}}{\memglodesc{(\ref {diff.mods.to.behavior.general})}} {\memgloref{}}|memjustarg}{1935} -\glossaryentry{diff.offsetof@ {\memgloterm{diff.offsetof}}{\memglodesc{(\ref {diff.offsetof})}} {\memgloref{}}|memjustarg}{1936} -\glossaryentry{diff.malloc@ {\memgloterm{diff.malloc}}{\memglodesc{(\ref {diff.malloc})}} {\memgloref{}}|memjustarg}{1936} -\glossaryentry{depr@ {\memgloterm{depr}}{\memglodesc{(\ref {depr})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.general@ {\memgloterm{depr.general}}{\memglodesc{(\ref {depr.general})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.arith.conv.enum@ {\memgloterm{depr.arith.conv.enum}}{\memglodesc{(\ref {depr.arith.conv.enum})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.capture.this@ {\memgloterm{depr.capture.this}}{\memglodesc{(\ref {depr.capture.this})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.array.comp@ {\memgloterm{depr.array.comp}}{\memglodesc{(\ref {depr.array.comp})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.volatile.type@ {\memgloterm{depr.volatile.type}}{\memglodesc{(\ref {depr.volatile.type})}} {\memgloref{}}|memjustarg}{1937} -\glossaryentry{depr.static.constexpr@ {\memgloterm{depr.static.constexpr}}{\memglodesc{(\ref {depr.static.constexpr})}} {\memgloref{}}|memjustarg}{1938} -\glossaryentry{depr.local@ {\memgloterm{depr.local}}{\memglodesc{(\ref {depr.local})}} {\memgloref{}}|memjustarg}{1938} -\glossaryentry{depr.impldec@ {\memgloterm{depr.impldec}}{\memglodesc{(\ref {depr.impldec})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.lit@ {\memgloterm{depr.lit}}{\memglodesc{(\ref {depr.lit})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.template.template@ {\memgloterm{depr.template.template}}{\memglodesc{(\ref {depr.template.template})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.res.on.required@ {\memgloterm{depr.res.on.required}}{\memglodesc{(\ref {depr.res.on.required})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.numeric.limits.has.denorm@ {\memgloterm{depr.numeric.limits.has.denorm}}{\memglodesc{(\ref {depr.numeric.limits.has.denorm})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.c.macros@ {\memgloterm{depr.c.macros}}{\memglodesc{(\ref {depr.c.macros})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.relops@ {\memgloterm{depr.relops}}{\memglodesc{(\ref {depr.relops})}} {\memgloref{}}|memjustarg}{1939} -\glossaryentry{depr.str.strstreams@ {\memgloterm{depr.str.strstreams}}{\memglodesc{(\ref {depr.str.strstreams})}} {\memgloref{}}|memjustarg}{1940} -\glossaryentry{depr.strstream.syn@ {\memgloterm{depr.strstream.syn}}{\memglodesc{(\ref {depr.strstream.syn})}} {\memgloref{}}|memjustarg}{1940} -\glossaryentry{depr.strstreambuf@ {\memgloterm{depr.strstreambuf}}{\memglodesc{(\ref {depr.strstreambuf})}} {\memgloref{}}|memjustarg}{1940} -\glossaryentry{depr.strstreambuf.general@ {\memgloterm{depr.strstreambuf.general}}{\memglodesc{(\ref {depr.strstreambuf.general})}} {\memgloref{}}|memjustarg}{1940} -\glossaryentry{depr.strstreambuf.cons@ {\memgloterm{depr.strstreambuf.cons}}{\memglodesc{(\ref {depr.strstreambuf.cons})}} {\memgloref{}}|memjustarg}{1941} -\glossaryentry{depr.strstreambuf.members@ {\memgloterm{depr.strstreambuf.members}}{\memglodesc{(\ref {depr.strstreambuf.members})}} {\memgloref{}}|memjustarg}{1942} -\glossaryentry{depr.strstreambuf.virtuals@ {\memgloterm{depr.strstreambuf.virtuals}}{\memglodesc{(\ref {depr.strstreambuf.virtuals})}} {\memgloref{}}|memjustarg}{1943} -\glossaryentry{depr.istrstream@ {\memgloterm{depr.istrstream}}{\memglodesc{(\ref {depr.istrstream})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.istrstream.general@ {\memgloterm{depr.istrstream.general}}{\memglodesc{(\ref {depr.istrstream.general})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.istrstream.cons@ {\memgloterm{depr.istrstream.cons}}{\memglodesc{(\ref {depr.istrstream.cons})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.istrstream.members@ {\memgloterm{depr.istrstream.members}}{\memglodesc{(\ref {depr.istrstream.members})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.ostrstream@ {\memgloterm{depr.ostrstream}}{\memglodesc{(\ref {depr.ostrstream})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.ostrstream.general@ {\memgloterm{depr.ostrstream.general}}{\memglodesc{(\ref {depr.ostrstream.general})}} {\memgloref{}}|memjustarg}{1945} -\glossaryentry{depr.ostrstream.cons@ {\memgloterm{depr.ostrstream.cons}}{\memglodesc{(\ref {depr.ostrstream.cons})}} {\memgloref{}}|memjustarg}{1946} -\glossaryentry{depr.ostrstream.members@ {\memgloterm{depr.ostrstream.members}}{\memglodesc{(\ref {depr.ostrstream.members})}} {\memgloref{}}|memjustarg}{1946} -\glossaryentry{depr.strstream@ {\memgloterm{depr.strstream}}{\memglodesc{(\ref {depr.strstream})}} {\memgloref{}}|memjustarg}{1946} -\glossaryentry{depr.strstream.general@ {\memgloterm{depr.strstream.general}}{\memglodesc{(\ref {depr.strstream.general})}} {\memgloref{}}|memjustarg}{1946} -\glossaryentry{depr.strstream.cons@ {\memgloterm{depr.strstream.cons}}{\memglodesc{(\ref {depr.strstream.cons})}} {\memgloref{}}|memjustarg}{1947} -\glossaryentry{depr.strstream.dest@ {\memgloterm{depr.strstream.dest}}{\memglodesc{(\ref {depr.strstream.dest})}} {\memgloref{}}|memjustarg}{1947} -\glossaryentry{depr.strstream.oper@ {\memgloterm{depr.strstream.oper}}{\memglodesc{(\ref {depr.strstream.oper})}} {\memgloref{}}|memjustarg}{1947} -\glossaryentry{depr.cerrno@ {\memgloterm{depr.cerrno}}{\memglodesc{(\ref {depr.cerrno})}} {\memgloref{}}|memjustarg}{1947} -\glossaryentry{depr.default.allocator@ {\memgloterm{depr.default.allocator}}{\memglodesc{(\ref {depr.default.allocator})}} {\memgloref{}}|memjustarg}{1948} -\glossaryentry{depr.mem.poly.allocator.mem@ {\memgloterm{depr.mem.poly.allocator.mem}}{\memglodesc{(\ref {depr.mem.poly.allocator.mem})}} {\memgloref{}}|memjustarg}{1948} -\glossaryentry{depr.meta.types@ {\memgloterm{depr.meta.types}}{\memglodesc{(\ref {depr.meta.types})}} {\memgloref{}}|memjustarg}{1948} -\glossaryentry{depr.tuple@ {\memgloterm{depr.tuple}}{\memglodesc{(\ref {depr.tuple})}} {\memgloref{}}|memjustarg}{1949} -\glossaryentry{depr.variant@ {\memgloterm{depr.variant}}{\memglodesc{(\ref {depr.variant})}} {\memgloref{}}|memjustarg}{1950} -\glossaryentry{depr.iterator@ {\memgloterm{depr.iterator}}{\memglodesc{(\ref {depr.iterator})}} {\memgloref{}}|memjustarg}{1950} -\glossaryentry{depr.move.iter.elem@ {\memgloterm{depr.move.iter.elem}}{\memglodesc{(\ref {depr.move.iter.elem})}} {\memgloref{}}|memjustarg}{1950} -\glossaryentry{depr.util.smartptr.shared.atomic@ {\memgloterm{depr.util.smartptr.shared.atomic}}{\memglodesc{(\ref {depr.util.smartptr.shared.atomic})}} {\memgloref{}}|memjustarg}{1951} -\glossaryentry{depr.string.capacity@ {\memgloterm{depr.string.capacity}}{\memglodesc{(\ref {depr.string.capacity})}} {\memgloref{}}|memjustarg}{1953} -\glossaryentry{depr.locale.stdcvt@ {\memgloterm{depr.locale.stdcvt}}{\memglodesc{(\ref {depr.locale.stdcvt})}} {\memgloref{}}|memjustarg}{1953} -\glossaryentry{depr.locale.stdcvt.general@ {\memgloterm{depr.locale.stdcvt.general}}{\memglodesc{(\ref {depr.locale.stdcvt.general})}} {\memgloref{}}|memjustarg}{1953} -\glossaryentry{depr.codecvt.syn@ {\memgloterm{depr.codecvt.syn}}{\memglodesc{(\ref {depr.codecvt.syn})}} {\memgloref{}}|memjustarg}{1953} -\glossaryentry{depr.locale.stdcvt.req@ {\memgloterm{depr.locale.stdcvt.req}}{\memglodesc{(\ref {depr.locale.stdcvt.req})}} {\memgloref{}}|memjustarg}{1954} -\glossaryentry{depr.conversions@ {\memgloterm{depr.conversions}}{\memglodesc{(\ref {depr.conversions})}} {\memgloref{}}|memjustarg}{1954} -\glossaryentry{depr.conversions.general@ {\memgloterm{depr.conversions.general}}{\memglodesc{(\ref {depr.conversions.general})}} {\memgloref{}}|memjustarg}{1954} -\glossaryentry{depr.conversions.string@ {\memgloterm{depr.conversions.string}}{\memglodesc{(\ref {depr.conversions.string})}} {\memgloref{}}|memjustarg}{1954} -\glossaryentry{depr.conversions.buffer@ {\memgloterm{depr.conversions.buffer}}{\memglodesc{(\ref {depr.conversions.buffer})}} {\memgloref{}}|memjustarg}{1956} -\glossaryentry{depr.locale.category@ {\memgloterm{depr.locale.category}}{\memglodesc{(\ref {depr.locale.category})}} {\memgloref{}}|memjustarg}{1958} -\glossaryentry{depr.fs.path.factory@ {\memgloterm{depr.fs.path.factory}}{\memglodesc{(\ref {depr.fs.path.factory})}} {\memgloref{}}|memjustarg}{1958} -\glossaryentry{depr.atomics@ {\memgloterm{depr.atomics}}{\memglodesc{(\ref {depr.atomics})}} {\memgloref{}}|memjustarg}{1958} -\glossaryentry{depr.atomics.general@ {\memgloterm{depr.atomics.general}}{\memglodesc{(\ref {depr.atomics.general})}} {\memgloref{}}|memjustarg}{1958} -\glossaryentry{depr.atomics.volatile@ {\memgloterm{depr.atomics.volatile}}{\memglodesc{(\ref {depr.atomics.volatile})}} {\memgloref{}}|memjustarg}{1959} -\glossaryentry{depr.atomics.nonmembers@ {\memgloterm{depr.atomics.nonmembers}}{\memglodesc{(\ref {depr.atomics.nonmembers})}} {\memgloref{}}|memjustarg}{1959} -\glossaryentry{depr.atomics.types.operations@ {\memgloterm{depr.atomics.types.operations}}{\memglodesc{(\ref {depr.atomics.types.operations})}} {\memgloref{}}|memjustarg}{1959} -\glossaryentry{uaxid@ {\memgloterm{uaxid}}{\memglodesc{(\ref {uaxid})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.general@ {\memgloterm{uaxid.general}}{\memglodesc{(\ref {uaxid.general})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.def@ {\memgloterm{uaxid.def}}{\memglodesc{(\ref {uaxid.def})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.def.general@ {\memgloterm{uaxid.def.general}}{\memglodesc{(\ref {uaxid.def.general})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.def.rfmt@ {\memgloterm{uaxid.def.rfmt}}{\memglodesc{(\ref {uaxid.def.rfmt})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.def.stable@ {\memgloterm{uaxid.def.stable}}{\memglodesc{(\ref {uaxid.def.stable})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.immutable@ {\memgloterm{uaxid.immutable}}{\memglodesc{(\ref {uaxid.immutable})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.pattern@ {\memgloterm{uaxid.pattern}}{\memglodesc{(\ref {uaxid.pattern})}} {\memgloref{}}|memjustarg}{1960} -\glossaryentry{uaxid.eqn@ {\memgloterm{uaxid.eqn}}{\memglodesc{(\ref {uaxid.eqn})}} {\memgloref{}}|memjustarg}{1961} -\glossaryentry{uaxid.eqci@ {\memgloterm{uaxid.eqci}}{\memglodesc{(\ref {uaxid.eqci})}} {\memgloref{}}|memjustarg}{1961} -\glossaryentry{uaxid.filter@ {\memgloterm{uaxid.filter}}{\memglodesc{(\ref {uaxid.filter})}} {\memgloref{}}|memjustarg}{1961} -\glossaryentry{uaxid.filterci@ {\memgloterm{uaxid.filterci}}{\memglodesc{(\ref {uaxid.filterci})}} {\memgloref{}}|memjustarg}{1961} -\glossaryentry{uaxid.hashtag@ {\memgloterm{uaxid.hashtag}}{\memglodesc{(\ref {uaxid.hashtag})}} {\memgloref{}}|memjustarg}{1961} +accumulate +adjacent.difference +adjustfield.manip +alg.adjacent.find +alg.all.of +alg.all_of +alg.any.of +alg.any_of +alg.binary.search +alg.c.library +alg.clamp +alg.copy +alg.count +alg.equal +alg.fill +alg.find +alg.find.end +alg.find.first.of +alg.foreach +alg.generate +alg.heap.operations +alg.is.permutation +alg.is_permutation +alg.lex.comparison +alg.merge +alg.min.max +alg.modifying.operations +alg.move +alg.none.of +alg.none_of +alg.nonmodifying +alg.nth.element +alg.partitions +alg.permutation.generators +alg.random.sample +alg.random.shuffle +alg.remove +alg.replace +alg.req +alg.req.general +alg.req.ind.cmp +alg.req.ind.copy +alg.req.ind.move +alg.req.ind.swap +alg.req.mergeable +alg.req.permutable +alg.req.sortable +alg.reverse +alg.rotate +alg.search +alg.set.operations +alg.shift +alg.sort +alg.sorting +alg.swap +alg.three.way +alg.transform +alg.unique +algorithm.stable +algorithm.syn +algorithms +algorithms.general +algorithms.parallel +algorithms.parallel.defns +algorithms.parallel.exceptions +algorithms.parallel.exec +algorithms.parallel.overloads +algorithms.parallel.user +algorithms.requirements +algorithms.results +alloc.errors +allocator.adaptor +allocator.adaptor.cnstr +allocator.adaptor.members +allocator.adaptor.syn +allocator.adaptor.types +allocator.globals +allocator.members +allocator.requirements +allocator.requirements.completeness +allocator.tag +allocator.traits +allocator.traits.members +allocator.traits.types +allocator.uses +allocator.uses.construction +allocator.uses.trait +alt.headers +any +any.assign +any.bad.any.cast +any.bad_any_cast +any.class +any.cons +any.modifiers +any.nonmembers +any.observers +any.synop +arithmetic.operations +arithmetic.operations.divides +arithmetic.operations.minus +arithmetic.operations.modulus +arithmetic.operations.multiplies +arithmetic.operations.negate +arithmetic.operations.plus +array +array.cons +array.creation +array.data +array.fill +array.members +array.overview +array.size +array.special +array.swap +array.syn +array.tuple +array.zero +assertions +assertions.assert +associative +associative.general +associative.map.syn +associative.reqmts +associative.reqmts.except +associative.set.syn +atomics +atomics.alias +atomics.fences +atomics.flag +atomics.general +atomics.lockfree +atomics.nonmembers +atomics.order +atomics.ref.float +atomics.ref.generic +atomics.ref.int +atomics.ref.memop +atomics.ref.ops +atomics.ref.pointer +atomics.syn +atomics.types.float +atomics.types.generic +atomics.types.int +atomics.types.memop +atomics.types.operations +atomics.types.pointer +atomics.wait +back.insert.iter.cons +back.insert.iter.op* +back.insert.iter.op++ +back.insert.iter.op= +back.insert.iter.ops +back.insert.iterator +back.inserter +bad.alloc +bad.cast +bad.exception +bad.typeid +barrier.syn +basefield.manip +basic +basic.align +basic.compound +basic.def +basic.def.odr +basic.exec +basic.fundamental +basic.funscope +basic.indet +basic.ios.cons +basic.ios.members +basic.life +basic.link +basic.lookup +basic.lookup.argdep +basic.lookup.classref +basic.lookup.elab +basic.lookup.qual +basic.lookup.udir +basic.lookup.unqual +basic.lval +basic.memobj +basic.namespace +basic.pre +basic.scope +basic.scope.block +basic.scope.class +basic.scope.declarative +basic.scope.enum +basic.scope.hiding +basic.scope.namespace +basic.scope.param +basic.scope.pdecl +basic.scope.proto +basic.scope.temp +basic.start +basic.start.dynamic +basic.start.main +basic.start.static +basic.start.term +basic.stc +basic.stc.auto +basic.stc.dynamic +basic.stc.dynamic.allocation +basic.stc.dynamic.deallocation +basic.stc.dynamic.safety +basic.stc.inherit +basic.stc.static +basic.stc.thread +basic.string +basic.string.hash +basic.string.literals +basic.type.qualifier +basic.types +bidirectional.iterators +binary.search +bit +bit.cast +bit.count +bit.endian +bit.general +bit.pow.two +bit.rotate +bit.syn +bitmask.types +bitset +bitset.cons +bitset.hash +bitset.members +bitset.operators +bitset.syn +bitwise.operations +bitwise.operations.and +bitwise.operations.not +bitwise.operations.or +bitwise.operations.xor +byte.strings +c.files +c.locales +c.malloc +c.math +c.math.abs +c.math.fpclass +c.math.hypot3 +c.math.lerp +c.math.rand +c.mb.wcs +c.strings +cassert.syn +category.collate +category.ctype +category.messages +category.monetary +category.numeric +category.time +cctype.syn +cerrno.syn +cfenv +cfenv.syn +cfloat.syn +char.traits +char.traits.require +char.traits.specializations +char.traits.specializations.char +char.traits.specializations.char16.t +char.traits.specializations.char16_t +char.traits.specializations.char32.t +char.traits.specializations.char32_t +char.traits.specializations.char8.t +char.traits.specializations.wchar.t +char.traits.typedefs +character.seq +charconv +charconv.from.chars +charconv.syn +charconv.to.chars +cinttypes.syn +class +class.abstract +class.access +class.access.base +class.access.nest +class.access.spec +class.access.virt +class.base.init +class.bit +class.cdtor +class.compare +class.compare.default +class.compare.secondary +class.conv +class.conv.ctor +class.conv.fct +class.copy +class.copy.assign +class.copy.ctor +class.copy.elision +class.ctor +class.default.ctor +class.derived +class.dtor +class.eq +class.expl.init +class.free +class.friend +class.gslice +class.gslice.overview +class.inhctor.init +class.init +class.local +class.mem +class.member.lookup +class.mfct +class.mfct.non-static +class.mfct.non-static.general +class.mi +class.name +class.nest +class.nested.type +class.paths +class.pre +class.prop +class.protected +class.qual +class.slice +class.slice.overview +class.spaceship +class.static +class.static.data +class.static.mfct +class.temporary +class.this +class.union +class.union.anon +class.virtual +classification +climits.syn +clocale.syn +cmath.syn +cmp +cmp.alg +cmp.categories +cmp.categories.pre +cmp.common +cmp.concept +cmp.partialord +cmp.result +cmp.strongord +cmp.weakord +cmplx.over +common.iter.access +common.iter.cmp +common.iter.const +common.iter.cust +common.iter.nav +common.iter.types +common.iterator +compare.syn +comparisons +comparisons.equal.to +comparisons.equal_to +comparisons.greater +comparisons.greater.equal +comparisons.greater_equal +comparisons.less +comparisons.less.equal +comparisons.less_equal +comparisons.not.equal.to +comparisons.not_equal_to +comparisons.three.way +complex +complex.literals +complex.member.ops +complex.members +complex.numbers +complex.ops +complex.special +complex.syn +complex.transcendentals +complex.value.ops +compliance +concept.assignable +concept.booleantestable +concept.common +concept.commonref +concept.constructible +concept.convertible +concept.copyconstructible +concept.default.init +concept.derived +concept.destructible +concept.equalitycomparable +concept.equiv +concept.invocable +concept.moveconstructible +concept.predicate +concept.regularinvocable +concept.relation +concept.same +concept.strictweakorder +concept.swappable +concept.totallyordered +concepts +concepts.arithmetic +concepts.callable +concepts.callable.general +concepts.compare +concepts.compare.general +concepts.equality +concepts.general +concepts.lang +concepts.lang.general +concepts.object +concepts.syn +condition.variable.syn +condition_variable.syn +conforming +conforming.overview +cons.slice +constexpr.functions +constraints +constraints.overview +container.adaptors +container.adaptors.general +container.gen.reqmts +container.insert.return +container.node +container.node.cons +container.node.dtor +container.node.modifiers +container.node.observers +container.node.overview +container.requirements +container.requirements.dataraces +container.requirements.general +containers +containers.general +contents +conv +conv.array +conv.bool +conv.double +conv.fctptr +conv.fpint +conv.fpprom +conv.func +conv.integral +conv.lval +conv.mem +conv.prom +conv.ptr +conv.qual +conv.rank +conv.rval +conventions +conversions +conversions.character +coroutine.handle +coroutine.handle.compare +coroutine.handle.con +coroutine.handle.export.import +coroutine.handle.hash +coroutine.handle.noop +coroutine.handle.noop.address +coroutine.handle.noop.observers +coroutine.handle.noop.promise +coroutine.handle.noop.resumption +coroutine.handle.observers +coroutine.handle.promise +coroutine.handle.resumption +coroutine.noop +coroutine.noop.coroutine +coroutine.promise.noop +coroutine.syn +coroutine.traits +coroutine.traits.primary +coroutine.trivial.awaitables +counted.iter.access +counted.iter.cmp +counted.iter.const +counted.iter.cust +counted.iter.elem +counted.iter.nav +counted.iterator +cpp +cpp.concat +cpp.cond +cpp.error +cpp.import +cpp.include +cpp.line +cpp.module +cpp.null +cpp.pragma +cpp.pragma.op +cpp.pre +cpp.predefined +cpp.replace +cpp.rescan +cpp.scope +cpp.stringize +cpp.subst +csetjmp.syn +csignal.syn +cstdarg.syn +cstddef.syn +cstdint +cstdint.general +cstdint.syn +cstdio.syn +cstdlib.syn +cstring.syn +ctime.syn +cuchar.syn +customization.point.object +cwchar.syn +cwctype.syn +dcl.align +dcl.ambig.res +dcl.array +dcl.asm +dcl.attr +dcl.attr.depend +dcl.attr.deprecated +dcl.attr.fallthrough +dcl.attr.grammar +dcl.attr.likelihood +dcl.attr.nodiscard +dcl.attr.noreturn +dcl.attr.nouniqueaddr +dcl.attr.unused +dcl.constexpr +dcl.constinit +dcl.dcl +dcl.decl +dcl.enum +dcl.fct +dcl.fct.def +dcl.fct.def.coroutine +dcl.fct.def.default +dcl.fct.def.delete +dcl.fct.def.general +dcl.fct.default +dcl.fct.spec +dcl.friend +dcl.init +dcl.init.aggr +dcl.init.list +dcl.init.ref +dcl.init.string +dcl.inline +dcl.link +dcl.meaning +dcl.mptr +dcl.name +dcl.pre +dcl.ptr +dcl.ref +dcl.spec +dcl.spec.auto +dcl.stc +dcl.struct.bind +dcl.type +dcl.type.auto.deduct +dcl.type.class.deduct +dcl.type.cv +dcl.type.decltype +dcl.type.elab +dcl.type.simple +dcl.typedef +declval +default.allocator +default.sentinels +definitions +defns.access +defns.arbitrary.stream +defns.argument +defns.argument.macro +defns.argument.templ +defns.argument.throw +defns.block +defns.block.stmt +defns.character +defns.character.container +defns.comparison +defns.component +defns.cond.supp +defns.const.subexpr +defns.deadlock +defns.default.behavior.func +defns.default.behavior.impl +defns.diagnostic +defns.direct-non-list-init +defns.dynamic.type +defns.dynamic.type.prvalue +defns.expression-equivalent +defns.handler +defns.ill.formed +defns.impl.defined +defns.impl.limits +defns.iostream.templates +defns.locale.specific +defns.modifier +defns.move.assign +defns.move.constr +defns.multibyte +defns.ntcts +defns.observer +defns.order.ptr +defns.parameter +defns.parameter.macro +defns.parameter.templ +defns.prog.def.spec +defns.prog.def.type +defns.projection +defns.referenceable +defns.regex.collating.element +defns.regex.finite.state.machine +defns.regex.format.specifier +defns.regex.matched +defns.regex.primary.equivalence.class +defns.regex.regular.expression +defns.regex.subexpression +defns.replacement +defns.repositional.stream +defns.required.behavior +defns.reserved.function +defns.signature +defns.signature.friend +defns.signature.member +defns.signature.member.spec +defns.signature.member.templ +defns.signature.spec +defns.signature.templ +defns.signature.templ.friend +defns.stable +defns.static.type +defns.traits +defns.unblock +defns.undefined +defns.unspecified +defns.valid +defns.well.formed +denorm.style +depr +depr.arith.conv.enum +depr.array.comp +depr.atomics +depr.atomics.flag +depr.atomics.nonmembers +depr.atomics.types.operations +depr.atomics.volatile +depr.c.headers +depr.c.headers.general +depr.c.headers.other +depr.capture.this +depr.ccomplex.syn +depr.codecvt.syn +depr.comma.subscript +depr.complex.h.syn +depr.conversions +depr.conversions.buffer +depr.conversions.general +depr.conversions.string +depr.cpp.headers +depr.cstdalign.syn +depr.cstdbool.syn +depr.ctgmath.syn +depr.default.allocator +depr.default.allocator +depr.except.spec +depr.fs.path.factory +depr.func.adaptor.binding +depr.func.adaptor.typedefs +depr.impldec +depr.iso646.h.syn +depr.istrstream +depr.istrstream.cons +depr.istrstream.general +depr.istrstream.members +depr.iterator.basic +depr.iterator.primitives +depr.local +depr.locale.category +depr.locale.stdcvt +depr.locale.stdcvt.general +depr.locale.stdcvt.req +depr.mem.poly.allocator.mem +depr.meta.types +depr.move.iter.elem +depr.negators +depr.ostrstream +depr.ostrstream.cons +depr.ostrstream.general +depr.ostrstream.members +depr.relops +depr.res.on.required +depr.static.constexpr +depr.static_constexpr +depr.stdalign.h.syn +depr.stdbool.h.syn +depr.storage.iterator +depr.str.strstreams +depr.string.capacity +depr.strstream +depr.strstream.cons +depr.strstream.dest +depr.strstream.general +depr.strstream.oper +depr.strstream.syn +depr.strstreambuf +depr.strstreambuf.cons +depr.strstreambuf.general +depr.strstreambuf.members +depr.strstreambuf.virtuals +depr.temporary.buffer +depr.tgmath.h.syn +depr.tuple +depr.uncaught +depr.util.smartptr.shared.atomic +depr.util.smartptr.shared.obs +depr.variant +depr.volatile.type +depr.weak.result_type +deque +deque.capacity +deque.cons +deque.erasure +deque.modifiers +deque.overview +deque.special +deque.syn +derivation +derived.classes +description +diagnostics +diagnostics.general +diff +diff.basic +diff.char16 +diff.class +diff.conv +diff.cpp +diff.cpp03 +diff.cpp03.algorithms +diff.cpp03.class +diff.cpp03.containers +diff.cpp03.conv +diff.cpp03.dcl.dcl +diff.cpp03.dcl.decl +diff.cpp03.diagnostics +diff.cpp03.expr +diff.cpp03.input.output +diff.cpp03.language.support +diff.cpp03.lex +diff.cpp03.library +diff.cpp03.numerics +diff.cpp03.special +diff.cpp03.strings +diff.cpp03.temp +diff.cpp03.utilities +diff.cpp11 +diff.cpp11.basic +diff.cpp11.dcl.dcl +diff.cpp11.dcl.decl +diff.cpp11.expr +diff.cpp11.input.output +diff.cpp11.lex +diff.cpp11.library +diff.cpp14 +diff.cpp14.class +diff.cpp14.containers +diff.cpp14.dcl.dcl +diff.cpp14.decl +diff.cpp14.depr +diff.cpp14.except +diff.cpp14.expr +diff.cpp14.lex +diff.cpp14.library +diff.cpp14.special +diff.cpp14.string +diff.cpp14.temp +diff.cpp14.utilities +diff.cpp17 +diff.cpp17.alg.reqs +diff.cpp17.basic +diff.cpp17.class +diff.cpp17.containers +diff.cpp17.dcl.dcl +diff.cpp17.depr +diff.cpp17.except +diff.cpp17.expr +diff.cpp17.input.output +diff.cpp17.iterators +diff.cpp17.lex +diff.cpp17.library +diff.cpp17.over +diff.cpp17.temp +diff.dcl +diff.decl +diff.expr +diff.header.assert.h +diff.header.iso646.h +diff.header.stdalign.h +diff.header.stdbool.h +diff.iso +diff.lex +diff.library +diff.malloc +diff.mods.to.behavior +diff.mods.to.declarations +diff.mods.to.definitions +diff.mods.to.headers +diff.null +diff.offsetof +diff.special +diff.stat +diff.wchar.t +domain.error +enum +enum.udecl +enumerated.types +equal.range +errno +error.reporting +except +except.ctor +except.handle +except.nested +except.pre +except.spec +except.special +except.terminate +except.throw +except.uncaught +exception +exception.syn +exception.terminate +exclusive.scan +execpol +execpol.general +execpol.objects +execpol.par +execpol.parunseq +execpol.seq +execpol.type +execpol.unseq +execution.syn +expos.only.func +expos.only.types +expr +expr.add +expr.alignof +expr.arith.conv +expr.ass +expr.await +expr.bit.and +expr.call +expr.cast +expr.comma +expr.compound +expr.cond +expr.const +expr.const.cast +expr.context +expr.delete +expr.dynamic.cast +expr.eq +expr.log.and +expr.log.or +expr.mptr.oper +expr.mul +expr.new +expr.or +expr.post +expr.post.incr +expr.pre +expr.pre.incr +expr.prim +expr.prim.fold +expr.prim.id +expr.prim.id.dtor +expr.prim.id.qual +expr.prim.id.unqual +expr.prim.lambda +expr.prim.lambda.capture +expr.prim.lambda.closure +expr.prim.literal +expr.prim.paren +expr.prim.req +expr.prim.req.compound +expr.prim.req.nested +expr.prim.req.simple +expr.prim.req.type +expr.prim.this +expr.prop +expr.pseudo +expr.ref +expr.reinterpret.cast +expr.rel +expr.shift +expr.sizeof +expr.spaceship +expr.static.cast +expr.sub +expr.throw +expr.type +expr.type.conv +expr.typeid +expr.unary +expr.unary.noexcept +expr.unary.op +expr.xor +expr.yield +ext.manip +extern.names +extern.types +facet.ctype.char.dtor +facet.ctype.char.members +facet.ctype.char.statics +facet.ctype.char.virtuals +facet.ctype.special +facet.num.get.members +facet.num.get.virtuals +facet.num.put.members +facet.num.put.virtuals +facet.numpunct +facet.numpunct.members +facet.numpunct.virtuals +facets.examples +file.streams +filebuf +filebuf.assign +filebuf.cons +filebuf.members +filebuf.virtuals +filesystems +floatfield.manip +fmtflags.manip +fmtflags.state +format +format.arg +format.arg.store +format.args +format.arguments +format.context +format.err.report +format.error +format.formatter +format.formatter.spec +format.functions +format.parse.ctx +format.string +format.string.general +format.string.std +format.syn +formatter.requirements +forward +forward.iterators +forward.list.erasure +forward.list.syn +forward_list.syn +forwardlist +forwardlist.access +forwardlist.cons +forwardlist.iter +forwardlist.modifiers +forwardlist.ops +forwardlist.overview +forwardlist.spec +fp.style +fpos +fpos.members +fpos.operations +front.insert.iter.cons +front.insert.iter.op* +front.insert.iter.op++ +front.insert.iter.op= +front.insert.iter.ops +front.insert.iterator +front.inserter +fs.class.directory.entry +fs.class.directory.iterator +fs.class.directory_entry +fs.class.directory_iterator +fs.class.file.status +fs.class.file_status +fs.class.filesystem.error +fs.class.filesystem_error +fs.class.path +fs.class.rec.dir.itr +fs.conform.9945 +fs.conform.os +fs.conformance +fs.definitions +fs.dir.entry.cons +fs.dir.entry.mods +fs.dir.entry.obs +fs.dir.itr.members +fs.dir.itr.nonmembers +fs.enum +fs.enum.copy.opts +fs.enum.dir.opts +fs.enum.file.type +fs.enum.file_type +fs.enum.path.format +fs.enum.perm.opts +fs.enum.perms +fs.err.report +fs.file.status.cons +fs.file.status.mods +fs.file.status.obs +fs.file_status.cons +fs.file_status.mods +fs.file_status.obs +fs.filesystem.error.members +fs.filesystem.syn +fs.filesystem_error.members +fs.general +fs.norm.ref +fs.op.absolute +fs.op.canonical +fs.op.copy +fs.op.copy.file +fs.op.copy.symlink +fs.op.copy_file +fs.op.copy_symlink +fs.op.create.dir.symlk +fs.op.create.directories +fs.op.create.directory +fs.op.create.hard.lk +fs.op.create.symlink +fs.op.create_dir_symlk +fs.op.create_directories +fs.op.create_directory +fs.op.create_hard_lk +fs.op.create_symlink +fs.op.current.path +fs.op.current_path +fs.op.equivalent +fs.op.exists +fs.op.file.size +fs.op.file_size +fs.op.funcs +fs.op.hard.lk.ct +fs.op.hard_lk_ct +fs.op.is.block.file +fs.op.is.char.file +fs.op.is.directory +fs.op.is.empty +fs.op.is.fifo +fs.op.is.other +fs.op.is.regular.file +fs.op.is.socket +fs.op.is.symlink +fs.op.is_block_file +fs.op.is_char_file +fs.op.is_directory +fs.op.is_empty +fs.op.is_fifo +fs.op.is_other +fs.op.is_regular_file +fs.op.is_socket +fs.op.is_symlink +fs.op.last.write.time +fs.op.last_write_time +fs.op.permissions +fs.op.proximate +fs.op.read.symlink +fs.op.read_symlink +fs.op.relative +fs.op.remove +fs.op.remove.all +fs.op.remove_all +fs.op.rename +fs.op.resize.file +fs.op.resize_file +fs.op.space +fs.op.status +fs.op.status.known +fs.op.status_known +fs.op.symlink.status +fs.op.symlink_status +fs.op.temp.dir.path +fs.op.temp_dir_path +fs.op.weakly.canonical +fs.op.weakly_canonical +fs.path.append +fs.path.assign +fs.path.compare +fs.path.concat +fs.path.construct +fs.path.cvt +fs.path.decompose +fs.path.factory +fs.path.fmt.cvt +fs.path.gen +fs.path.generic +fs.path.generic.obs +fs.path.io +fs.path.itr +fs.path.member +fs.path.modifiers +fs.path.native.obs +fs.path.nonmember +fs.path.query +fs.path.req +fs.path.type.cvt +fs.race.behavior +fs.rec.dir.itr.members +fs.rec.dir.itr.nonmembers +fs.req +fs.req.general +fs.req.namespace +fstream +fstream.assign +fstream.cons +fstream.members +fstream.syn +func.bind +func.bind.bind +func.bind.front +func.bind.isbind +func.bind.isplace +func.bind.place +func.def +func.identity +func.invoke +func.memfn +func.not.fn +func.not_fn +func.require +func.search +func.search.bm +func.search.bmh +func.search.default +func.wrap +func.wrap.badcall +func.wrap.badcall.const +func.wrap.func +func.wrap.func.alg +func.wrap.func.cap +func.wrap.func.con +func.wrap.func.inv +func.wrap.func.mod +func.wrap.func.nullptr +func.wrap.func.targ +function.objects +functional.syn +functions.within.classes +future.syn +futures +futures.async +futures.errors +futures.future.error +futures.future_error +futures.overview +futures.promise +futures.shared.future +futures.shared_future +futures.state +futures.task +futures.task.members +futures.task.nonmembers +futures.unique.future +futures.unique_future +get.new.handler +get.terminate +global.functions +gram +gram.basic +gram.class +gram.cpp +gram.dcl +gram.decl +gram.derived +gram.except +gram.expr +gram.key +gram.lex +gram.module +gram.over +gram.special +gram.stmt +gram.temp +gslice.access +gslice.array.assign +gslice.array.comp.assign +gslice.array.fill +gslice.cons +handler.functions +hardware.interference +hash.requirements +headers +hidden.friends +ifstream +ifstream.assign +ifstream.cons +ifstream.members +implimits +includes +inclusive.scan +incrementable.traits +indirect.array.assign +indirect.array.comp.assign +indirect.array.fill +indirectcallable +indirectcallable.general +indirectcallable.indirectinvocable +initializer.list.syn +initializer_list.syn +inner.product +input.iterators +input.output +input.output.general +input.streams +insert.iter.cons +insert.iter.op* +insert.iter.op++ +insert.iter.op= +insert.iter.ops +insert.iterator +insert.iterators +inserter +intro +intro.abstract +intro.ack +intro.compliance +intro.defs +intro.execution +intro.memory +intro.multithread +intro.object +intro.progress +intro.races +intro.refs +intro.scope +intro.structure +intseq +intseq.general +intseq.intseq +intseq.make +invalid.argument +iomanip.syn +ios +ios.base +ios.base.callback +ios.base.cons +ios.base.locales +ios.base.storage +ios.failure +ios.fmtflags +ios.init +ios.iostate +ios.members.static +ios.openmode +ios.overview +ios.seekdir +ios.syn +ios.types +ios::Init +ios::failure +ios::fmtflags +ios::iostate +ios::openmode +ios::seekdir +iosfwd.syn +iostate.flags +iostream.assign +iostream.cons +iostream.dest +iostream.format +iostream.forward +iostream.forward.overview +iostream.limits.imbue +iostream.objects +iostream.objects.overview +iostream.syn +iostreamclass +iostreams.base +iostreams.limits.pos +iostreams.requirements +iostreams.threadsafety +is.heap +is.sorted +istream +istream.assign +istream.cons +istream.extractors +istream.formatted +istream.formatted.arithmetic +istream.formatted.reqmts +istream.iterator +istream.iterator.cons +istream.iterator.ops +istream.manip +istream.rvalue +istream.sentry +istream.syn +istream.unformatted +istream::sentry +istreambuf.iterator +istreambuf.iterator.cons +istreambuf.iterator.ops +istreambuf.iterator.proxy +istringstream +istringstream.assign +istringstream.cons +istringstream.members +iterator.assoc.types +iterator.concept.bidir +iterator.concept.contiguous +iterator.concept.forward +iterator.concept.inc +iterator.concept.input +iterator.concept.iterator +iterator.concept.output +iterator.concept.random.access +iterator.concept.readable +iterator.concept.sentinel +iterator.concept.sizedsentinel +iterator.concept.winc +iterator.concept.writable +iterator.concepts +iterator.concepts.general +iterator.container +iterator.cpp17 +iterator.cust +iterator.cust.move +iterator.cust.swap +iterator.iterators +iterator.operations +iterator.primitives +iterator.range +iterator.requirements +iterator.requirements.general +iterator.synopsis +iterator.traits +iterators +iterators.common +iterators.counted +iterators.general +language.support +latch.syn +length.error +lex +lex.bool +lex.ccon +lex.charset +lex.comment +lex.digraph +lex.ext +lex.fcon +lex.header +lex.icon +lex.key +lex.literal +lex.literal.kinds +lex.name +lex.nullptr +lex.operators +lex.phases +lex.ppnumber +lex.pptoken +lex.separate +lex.string +lex.token +lib.types.movedfrom +library +library.c +library.general +limits.syn +list +list.capacity +list.cons +list.erasure +list.modifiers +list.ops +list.overview +list.special +list.syn +locale +locale.categories +locale.category +locale.codecvt +locale.codecvt.byname +locale.codecvt.members +locale.codecvt.virtuals +locale.collate +locale.collate.byname +locale.collate.members +locale.collate.virtuals +locale.cons +locale.convenience +locale.ctype +locale.ctype.byname +locale.ctype.members +locale.ctype.virtuals +locale.facet +locale.global.templates +locale.id +locale.members +locale.messages +locale.messages.byname +locale.messages.members +locale.messages.virtuals +locale.money.get +locale.money.get.members +locale.money.get.virtuals +locale.money.put +locale.money.put.members +locale.money.put.virtuals +locale.moneypunct +locale.moneypunct.byname +locale.moneypunct.members +locale.moneypunct.virtuals +locale.nm.put +locale.num.get +locale.numpunct +locale.numpunct.byname +locale.operators +locale.statics +locale.syn +locale.time.get +locale.time.get.byname +locale.time.get.members +locale.time.get.virtuals +locale.time.put +locale.time.put.byname +locale.time.put.members +locale.time.put.virtuals +locale.types +locales +localization +localization.general +logic.error +logical.operations +logical.operations.and +logical.operations.not +logical.operations.or +lower.bound +macro.names +make.heap +map +map.access +map.cons +map.erasure +map.modifiers +map.overview +map.special +mask.array.assign +mask.array.comp.assign +mask.array.fill +math.constants +mem.poly.allocator.class +mem.poly.allocator.ctor +mem.poly.allocator.eq +mem.poly.allocator.mem +mem.res +mem.res.class +mem.res.eq +mem.res.global +mem.res.monotonic.buffer +mem.res.monotonic.buffer.ctor +mem.res.monotonic.buffer.mem +mem.res.pool +mem.res.pool.ctor +mem.res.pool.mem +mem.res.pool.options +mem.res.pool.overview +mem.res.private +mem.res.public +mem.res.syn +member.functions +memory +memory.general +memory.syn +meta +meta.const.eval +meta.help +meta.logical +meta.member +meta.rel +meta.rqmts +meta.trans +meta.trans.arr +meta.trans.cv +meta.trans.other +meta.trans.ptr +meta.trans.ref +meta.trans.sign +meta.type.synop +meta.unary +meta.unary.cat +meta.unary.comp +meta.unary.prop +meta.unary.prop.query +mismatch +module +module.context +module.global.frag +module.import +module.interface +module.private.frag +module.reach +module.unit +move.iter.cons +move.iter.elem +move.iter.nav +move.iter.nonmember +move.iter.op.+ +move.iter.op.+= +move.iter.op.- +move.iter.op.-= +move.iter.op.comp +move.iter.op.const +move.iter.op.conv +move.iter.op.decr +move.iter.op.incr +move.iter.op.index +move.iter.op.ref +move.iter.op.star +move.iter.op= +move.iter.ops +move.iter.requirements +move.iterator +move.iterators +move.sent.ops +move.sentinel +multibyte.strings +multimap +multimap.cons +multimap.erasure +multimap.modifiers +multimap.overview +multimap.special +multiset +multiset.cons +multiset.erasure +multiset.overview +multiset.special +mutex.syn +namespace.alias +namespace.constraints +namespace.def +namespace.future +namespace.memdef +namespace.posix +namespace.qual +namespace.std +namespace.udecl +namespace.udir +namespace.unnamed +narrow.stream.objects +new.badlength +new.delete +new.delete.array +new.delete.dataraces +new.delete.placement +new.delete.single +new.handler +new.syn +nullablepointer.requirements +numarray +numbers +numbers.syn +numeric.iota +numeric.limits +numeric.limits.members +numeric.ops +numeric.ops.gcd +numeric.ops.lcm +numeric.ops.midpoint +numeric.ops.overview +numeric.requirements +numeric.special +numerics +numerics.defns +numerics.general +objects.within.classes +ofstream +ofstream.assign +ofstream.cons +ofstream.members +operators +optional +optional.assign +optional.bad.access +optional.comp.with.t +optional.comp_with_t +optional.ctor +optional.dtor +optional.general +optional.hash +optional.mod +optional.nullops +optional.nullopt +optional.observe +optional.optional +optional.relops +optional.specalg +optional.swap +optional.syn +organization +ostream +ostream.assign +ostream.cons +ostream.formatted +ostream.formatted.reqmts +ostream.inserters +ostream.inserters.arithmetic +ostream.inserters.character +ostream.iterator +ostream.iterator.cons.des +ostream.iterator.ops +ostream.manip +ostream.rvalue +ostream.seeks +ostream.sentry +ostream.syn +ostream.unformatted +ostream::sentry +ostreambuf.iter.cons +ostreambuf.iter.ops +ostreambuf.iterator +ostringstream +ostringstream.assign +ostringstream.cons +ostringstream.members +out.of.range +output.iterators +output.streams +over +over.ass +over.best.ics +over.binary +over.built +over.call +over.call.func +over.call.object +over.dcl +over.ics.ellipsis +over.ics.list +over.ics.rank +over.ics.ref +over.ics.scs +over.ics.user +over.inc +over.literal +over.load +over.match +over.match.best +over.match.call +over.match.class.deduct +over.match.conv +over.match.copy +over.match.ctor +over.match.funcs +over.match.list +over.match.oper +over.match.ref +over.match.viable +over.oper +over.over +over.pre +over.ref +over.sub +over.unary +overflow.error +pair.astuple +pair.piecewise +pairs +pairs.general +pairs.pair +pairs.spec +partial.sort +partial.sort.copy +partial.sum +pointer.conversion +pointer.traits +pointer.traits.functions +pointer.traits.optmem +pointer.traits.types +pop.heap +predef.iterators +priority.queue +priqueue.cons +priqueue.cons.alloc +priqueue.members +priqueue.overview +priqueue.special +projected +propagation +protection.within.classes +ptr.align +ptr.launder +push.heap +queue +queue.cons +queue.cons.alloc +queue.defn +queue.ops +queue.special +queue.syn +quoted.manip +rand +rand.adapt +rand.adapt.disc +rand.adapt.general +rand.adapt.ibits +rand.adapt.shuf +rand.device +rand.dist +rand.dist.bern +rand.dist.bern.bernoulli +rand.dist.bern.bin +rand.dist.bern.geo +rand.dist.bern.negbin +rand.dist.general +rand.dist.norm +rand.dist.norm.cauchy +rand.dist.norm.chisq +rand.dist.norm.f +rand.dist.norm.lognormal +rand.dist.norm.normal +rand.dist.norm.t +rand.dist.pois +rand.dist.pois.exp +rand.dist.pois.extreme +rand.dist.pois.gamma +rand.dist.pois.poisson +rand.dist.pois.weibull +rand.dist.samp +rand.dist.samp.discrete +rand.dist.samp.pconst +rand.dist.samp.plinear +rand.dist.uni +rand.dist.uni.int +rand.dist.uni.real +rand.eng +rand.eng.lcong +rand.eng.mers +rand.eng.sub +rand.predef +rand.req +rand.req.adapt +rand.req.dist +rand.req.eng +rand.req.genl +rand.req.seedseq +rand.req.urng +rand.synopsis +rand.util +rand.util.canonical +rand.util.seedseq +random.access.iterators +range.access +range.access.begin +range.access.cbegin +range.access.cend +range.access.crbegin +range.access.crend +range.access.end +range.access.rbegin +range.access.rend +range.adaptor.object +range.adaptors +range.all +range.cmp +range.common +range.common.overview +range.common.view +range.counted +range.dangling +range.drop +range.drop.overview +range.drop.view +range.drop.while +range.drop.while.overview +range.drop.while.view +range.elements +range.elements.iterator +range.elements.overview +range.elements.sentinel +range.elements.view +range.empty +range.empty.overview +range.empty.view +range.error +range.factories +range.filter +range.filter.iterator +range.filter.overview +range.filter.sentinel +range.filter.view +range.iota +range.iota.iterator +range.iota.overview +range.iota.sentinel +range.iota.view +range.istream +range.istream.iterator +range.istream.overview +range.istream.view +range.iter.op.advance +range.iter.op.distance +range.iter.op.next +range.iter.op.prev +range.iter.ops +range.join +range.join.iterator +range.join.overview +range.join.sentinel +range.join.view +range.prim.cdata +range.prim.data +range.prim.empty +range.prim.size +range.prim.ssize +range.range +range.ref.view +range.refinements +range.req +range.req.general +range.reverse +range.reverse.overview +range.reverse.view +range.semi.wrap +range.single +range.single.overview +range.single.view +range.sized +range.split +range.split.inner +range.split.outer +range.split.outer.value +range.split.overview +range.split.view +range.subrange +range.subrange.access +range.subrange.ctor +range.take +range.take.overview +range.take.sentinel +range.take.view +range.take.while +range.take.while.overview +range.take.while.sentinel +range.take.while.view +range.transform +range.transform.iterator +range.transform.overview +range.transform.sentinel +range.transform.view +range.utility +range.utility.helpers +range.view +ranges +ranges.general +ranges.syn +ratio +ratio.arithmetic +ratio.comparison +ratio.general +ratio.ratio +ratio.si +ratio.syn +re +re.alg +re.alg.match +re.alg.replace +re.alg.search +re.badexp +re.const +re.def +re.err +re.except +re.general +re.grammar +re.iter +re.matchflag +re.regex +re.regex.assign +re.regex.const +re.regex.construct +re.regex.locale +re.regex.nmswap +re.regex.nonmemb +re.regex.operations +re.regex.swap +re.regiter +re.regiter.cnstr +re.regiter.comp +re.regiter.deref +re.regiter.incr +re.req +re.results +re.results.acc +re.results.all +re.results.const +re.results.form +re.results.nonmember +re.results.size +re.results.state +re.results.swap +re.submatch +re.submatch.members +re.submatch.op +re.syn +re.synopt +re.tokiter +re.tokiter.cnstr +re.tokiter.comp +re.tokiter.deref +re.tokiter.incr +re.traits +readable.traits +reduce +reentrancy +refwrap +refwrap.access +refwrap.assign +refwrap.const +refwrap.helpers +refwrap.invoke +replacement.functions +requirements +res.on.arguments +res.on.data.races +res.on.exception.handling +res.on.expects +res.on.functions +res.on.headers +res.on.macro.definitions +res.on.objects +res.on.pointer.storage +res.on.required +res.on.requirements +reserved.names +reverse.iter.cmp +reverse.iter.cons +reverse.iter.conv +reverse.iter.elem +reverse.iter.make +reverse.iter.nav +reverse.iter.nonmember +reverse.iter.op"!= +reverse.iter.op+ +reverse.iter.op++ +reverse.iter.op+= +reverse.iter.op- +reverse.iter.op-- +reverse.iter.op-= +reverse.iter.op.star +reverse.iter.op< +reverse.iter.op<= +reverse.iter.op= +reverse.iter.op== +reverse.iter.op> +reverse.iter.op>= +reverse.iter.opdiff +reverse.iter.opindex +reverse.iter.opref +reverse.iter.ops +reverse.iter.opsum +reverse.iter.requirements +reverse.iterator +reverse.iterators +round.style +runtime.error +scoped.adaptor.operators +semaphore.syn +sequence.reqmts +sequences +sequences.general +set +set.cons +set.difference +set.erasure +set.intersection +set.new.handler +set.overview +set.special +set.symmetric.difference +set.terminate +set.union +sf.cmath +sf.cmath.assoc.laguerre +sf.cmath.assoc.legendre +sf.cmath.assoc_laguerre +sf.cmath.assoc_legendre +sf.cmath.beta +sf.cmath.comp.ellint.1 +sf.cmath.comp.ellint.2 +sf.cmath.comp.ellint.3 +sf.cmath.comp_ellint_1 +sf.cmath.comp_ellint_2 +sf.cmath.comp_ellint_3 +sf.cmath.cyl.bessel.i +sf.cmath.cyl.bessel.j +sf.cmath.cyl.bessel.k +sf.cmath.cyl.neumann +sf.cmath.cyl_bessel_i +sf.cmath.cyl_bessel_j +sf.cmath.cyl_bessel_k +sf.cmath.cyl_neumann +sf.cmath.ellint.1 +sf.cmath.ellint.2 +sf.cmath.ellint.3 +sf.cmath.ellint_1 +sf.cmath.ellint_2 +sf.cmath.ellint_3 +sf.cmath.expint +sf.cmath.hermite +sf.cmath.laguerre +sf.cmath.legendre +sf.cmath.riemann.zeta +sf.cmath.riemann_zeta +sf.cmath.sph.bessel +sf.cmath.sph.legendre +sf.cmath.sph.neumann +sf.cmath.sph_bessel +sf.cmath.sph_legendre +sf.cmath.sph_neumann +shared.mutex.syn +shared_mutex.syn +slice.access +slice.arr.assign +slice.arr.comp.assign +slice.arr.fill +slice.ops +smartptr +sort +sort.heap +source.location.syn +span.cons +span.deduct +span.elem +span.iterators +span.objectrep +span.obs +span.overview +span.sub +span.syn +special +special.mem.concepts +specialized.addressof +specialized.algorithms +specialized.construct +specialized.destroy +sstream.syn +stable.sort +stack +stack.cons +stack.cons.alloc +stack.defn +stack.ops +stack.special +stack.syn +std.exceptions +std.ios.manip +std.iterator.tags +std.manip +stdexcept.syn +stmt.ambig +stmt.block +stmt.break +stmt.cont +stmt.dcl +stmt.do +stmt.expr +stmt.for +stmt.goto +stmt.if +stmt.iter +stmt.jump +stmt.label +stmt.pre +stmt.ranged +stmt.return +stmt.return.coroutine +stmt.select +stmt.stmt +stmt.switch +stmt.while +stopcallback +stopcallback.cons +stopsource +stopsource.cons +stopsource.mem +stopsource.nonmembers +stoptoken +stoptoken.cons +stoptoken.mem +stoptoken.nonmembers +stream.buffers +stream.iterators +stream.types +streambuf +streambuf.assign +streambuf.buffer +streambuf.cons +streambuf.get.area +streambuf.locales +streambuf.members +streambuf.protected +streambuf.pub.get +streambuf.pub.pback +streambuf.pub.put +streambuf.put.area +streambuf.reqts +streambuf.syn +streambuf.virt.buffer +streambuf.virt.get +streambuf.virt.locales +streambuf.virt.pback +streambuf.virt.put +streambuf.virtuals +string.access +string.accessors +string.append +string.assign +string.capacity +string.classes +string.cmp +string.compare +string.cons +string.conversions +string.copy +string.ends.with +string.erase +string.erasure +string.find +string.find.first.not.of +string.find.first.of +string.find.last.not.of +string.find.last.of +string.insert +string.io +string.iterators +string.modifiers +string.nonmembers +string.op"!= +string.op+ +string.op+= +string.op.append +string.op.plus +string.op< +string.op<= +string.op> +string.op>= +string.operator== +string.ops +string.replace +string.require +string.rfind +string.special +string.starts.with +string.streams +string.substr +string.swap +string.syn +string.view +string.view.access +string.view.capacity +string.view.comparison +string.view.cons +string.view.deduct +string.view.find +string.view.hash +string.view.io +string.view.iterators +string.view.literals +string.view.modifiers +string.view.ops +string.view.synop +string.view.template +stringbuf +stringbuf.assign +stringbuf.cons +stringbuf.members +stringbuf.virtuals +strings +strings.general +stringstream +stringstream.assign +stringstream.cons +stringstream.members +structure +structure.elements +structure.requirements +structure.see.also +structure.specifications +structure.summary +support +support.coroutine +support.dynamic +support.exception +support.general +support.initlist +support.initlist.access +support.initlist.cons +support.initlist.range +support.limits +support.limits.general +support.rtti +support.runtime +support.signal +support.srcloc +support.srcloc.class +support.srcloc.cons +support.srcloc.obs +support.start.term +support.types +support.types.byteops +support.types.layout +support.types.nullptr +swappable.requirements +syncstream +syncstream.osyncstream +syncstream.osyncstream.cons +syncstream.osyncstream.members +syncstream.osyncstream.overview +syncstream.syn +syncstream.syncbuf +syncstream.syncbuf.assign +syncstream.syncbuf.cons +syncstream.syncbuf.members +syncstream.syncbuf.overview +syncstream.syncbuf.special +syncstream.syncbuf.virtuals +syntax +syserr +syserr.compare +syserr.errcat +syserr.errcat.derived +syserr.errcat.nonvirtuals +syserr.errcat.objects +syserr.errcat.overview +syserr.errcat.virtuals +syserr.errcode +syserr.errcode.constructors +syserr.errcode.modifiers +syserr.errcode.nonmembers +syserr.errcode.observers +syserr.errcode.overview +syserr.errcondition +syserr.errcondition.constructors +syserr.errcondition.modifiers +syserr.errcondition.nonmembers +syserr.errcondition.observers +syserr.errcondition.overview +syserr.hash +syserr.syserr +syserr.syserr.members +syserr.syserr.overview +system.error.syn +system_error.syn +temp +temp.alias +temp.arg +temp.arg.explicit +temp.arg.nontype +temp.arg.template +temp.arg.type +temp.class +temp.class.order +temp.class.spec +temp.class.spec.general +temp.class.spec.match +temp.class.spec.mfunc +temp.concept +temp.constr +temp.constr.atomic +temp.constr.constr +temp.constr.decl +temp.constr.normal +temp.constr.op +temp.constr.order +temp.decls +temp.deduct +temp.deduct.call +temp.deduct.conv +temp.deduct.decl +temp.deduct.funcaddr +temp.deduct.guide +temp.deduct.partial +temp.deduct.type +temp.dep +temp.dep.candidate +temp.dep.constexpr +temp.dep.expr +temp.dep.res +temp.dep.temp +temp.dep.type +temp.expl.spec +temp.explicit +temp.fct +temp.fct.spec +temp.friend +temp.func.order +temp.inject +temp.inst +temp.local +temp.mem +temp.mem.class +temp.mem.enum +temp.mem.func +temp.names +temp.nondep +temp.over +temp.over.link +temp.param +temp.point +temp.pre +temp.res +temp.spec +temp.static +temp.type +temp.variadic +template.bitset +template.gslice.array +template.gslice.array.overview +template.indirect.array +template.indirect.array.overview +template.mask.array +template.mask.array.overview +template.slice.array +template.slice.array.overview +template.valarray +template.valarray.overview +terminate +terminate.handler +thread +thread.barrier +thread.barrier.class +thread.condition +thread.condition.condvar +thread.condition.condvarany +thread.condition.nonmember +thread.condvarany.intwait +thread.condvarany.wait +thread.coord +thread.decaycopy +thread.general +thread.jthread.class +thread.jthread.cons +thread.jthread.mem +thread.jthread.special +thread.jthread.static +thread.jthread.stop +thread.latch +thread.latch.class +thread.lock +thread.lock.algorithm +thread.lock.guard +thread.lock.scoped +thread.lock.shared +thread.lock.shared.cons +thread.lock.shared.locking +thread.lock.shared.mod +thread.lock.shared.obs +thread.lock.unique +thread.lock.unique.cons +thread.lock.unique.locking +thread.lock.unique.mod +thread.lock.unique.obs +thread.mutex +thread.mutex.class +thread.mutex.recursive +thread.mutex.requirements +thread.mutex.requirements.general +thread.mutex.requirements.mutex +thread.once +thread.once.callonce +thread.once.onceflag +thread.req +thread.req.exception +thread.req.lockable +thread.req.lockable.basic +thread.req.lockable.general +thread.req.lockable.req +thread.req.lockable.timed +thread.req.native +thread.req.paramname +thread.req.timing +thread.sema +thread.sema.cnt +thread.sharedmutex.class +thread.sharedmutex.requirements +thread.sharedtimedmutex.class +thread.sharedtimedmutex.requirements +thread.stoptoken +thread.stoptoken.intro +thread.stoptoken.syn +thread.syn +thread.thread.algorithm +thread.thread.assign +thread.thread.class +thread.thread.constr +thread.thread.destr +thread.thread.id +thread.thread.member +thread.thread.static +thread.thread.this +thread.threads +thread.timedmutex.class +thread.timedmutex.recursive +thread.timedmutex.requirements +time +time.12 +time.cal +time.cal.day +time.cal.day.members +time.cal.day.nonmembers +time.cal.day.overview +time.cal.general +time.cal.last +time.cal.md +time.cal.md.members +time.cal.md.nonmembers +time.cal.md.overview +time.cal.mdlast +time.cal.month +time.cal.month.members +time.cal.month.nonmembers +time.cal.month.overview +time.cal.mwd +time.cal.mwd.members +time.cal.mwd.nonmembers +time.cal.mwd.overview +time.cal.mwdlast +time.cal.mwdlast.members +time.cal.mwdlast.nonmembers +time.cal.mwdlast.overview +time.cal.operators +time.cal.wd +time.cal.wd.members +time.cal.wd.nonmembers +time.cal.wd.overview +time.cal.wdidx +time.cal.wdidx.members +time.cal.wdidx.nonmembers +time.cal.wdidx.overview +time.cal.wdlast +time.cal.wdlast.members +time.cal.wdlast.nonmembers +time.cal.wdlast.overview +time.cal.year +time.cal.year.members +time.cal.year.nonmembers +time.cal.year.overview +time.cal.ym +time.cal.ym.members +time.cal.ym.nonmembers +time.cal.ym.overview +time.cal.ymd +time.cal.ymd.members +time.cal.ymd.nonmembers +time.cal.ymd.overview +time.cal.ymdlast +time.cal.ymdlast.members +time.cal.ymdlast.nonmembers +time.cal.ymdlast.overview +time.cal.ymwd +time.cal.ymwd.members +time.cal.ymwd.nonmembers +time.cal.ymwd.overview +time.cal.ymwdlast +time.cal.ymwdlast.members +time.cal.ymwdlast.nonmembers +time.cal.ymwdlast.overview +time.clock +time.clock.cast +time.clock.cast.fn +time.clock.cast.id +time.clock.cast.sys +time.clock.cast.sys.utc +time.clock.cast.utc +time.clock.conv +time.clock.file +time.clock.file.members +time.clock.file.nonmembers +time.clock.file.overview +time.clock.gps +time.clock.gps.members +time.clock.gps.nonmembers +time.clock.gps.overview +time.clock.hires +time.clock.local +time.clock.req +time.clock.steady +time.clock.system +time.clock.system.members +time.clock.system.nonmembers +time.clock.system.overview +time.clock.tai +time.clock.tai.members +time.clock.tai.nonmembers +time.clock.tai.overview +time.clock.utc +time.clock.utc.members +time.clock.utc.nonmembers +time.clock.utc.overview +time.duration +time.duration.alg +time.duration.arithmetic +time.duration.cast +time.duration.comparisons +time.duration.cons +time.duration.io +time.duration.literals +time.duration.nonmember +time.duration.observer +time.duration.special +time.format +time.general +time.hms +time.hms.members +time.hms.nonmembers +time.hms.overview +time.parse +time.point +time.point.arithmetic +time.point.cast +time.point.comparisons +time.point.cons +time.point.nonmember +time.point.observer +time.point.special +time.syn +time.traits +time.traits.duration.values +time.traits.duration_values +time.traits.is.clock +time.traits.is.fp +time.traits.is_fp +time.traits.specializations +time.zone +time.zone.db +time.zone.db.access +time.zone.db.list +time.zone.db.remote +time.zone.db.tzdb +time.zone.exception +time.zone.exception.ambig +time.zone.exception.nonexist +time.zone.general +time.zone.info +time.zone.info.local +time.zone.info.sys +time.zone.leap +time.zone.leap.members +time.zone.leap.nonmembers +time.zone.leap.overview +time.zone.link +time.zone.link.members +time.zone.link.nonmembers +time.zone.link.overview +time.zone.members +time.zone.nonmembers +time.zone.overview +time.zone.timezone +time.zone.zonedtime +time.zone.zonedtime.ctor +time.zone.zonedtime.members +time.zone.zonedtime.nonmembers +time.zone.zonedtime.overview +time.zone.zonedtraits +transform.exclusive.scan +transform.inclusive.scan +transform.reduce +tuple +tuple.apply +tuple.assign +tuple.cnstr +tuple.creation +tuple.elem +tuple.general +tuple.helper +tuple.rel +tuple.special +tuple.swap +tuple.syn +tuple.traits +tuple.tuple +type.descriptions +type.descriptions.general +type.index +type.index.hash +type.index.members +type.index.overview +type.index.synopsis +type.info +typeinfo.syn +uncaught.exceptions +underflow.error +uninitialized.construct.default +uninitialized.construct.value +uninitialized.copy +uninitialized.fill +uninitialized.move +unique.ptr +unique.ptr.create +unique.ptr.dltr +unique.ptr.dltr.dflt +unique.ptr.dltr.dflt1 +unique.ptr.dltr.general +unique.ptr.io +unique.ptr.runtime +unique.ptr.runtime.asgn +unique.ptr.runtime.ctor +unique.ptr.runtime.modifiers +unique.ptr.runtime.observers +unique.ptr.single +unique.ptr.single.asgn +unique.ptr.single.ctor +unique.ptr.single.dtor +unique.ptr.single.modifiers +unique.ptr.single.observers +unique.ptr.special +unord +unord.general +unord.hash +unord.map +unord.map.cnstr +unord.map.elem +unord.map.erasure +unord.map.modifiers +unord.map.overview +unord.map.swap +unord.map.syn +unord.multimap +unord.multimap.cnstr +unord.multimap.erasure +unord.multimap.modifiers +unord.multimap.overview +unord.multimap.swap +unord.multiset +unord.multiset.cnstr +unord.multiset.erasure +unord.multiset.overview +unord.multiset.swap +unord.req +unord.req.except +unord.set +unord.set.cnstr +unord.set.erasure +unord.set.overview +unord.set.swap +unord.set.syn +unreachable.sentinel +unreachable.sentinels +upper.bound +using +using.headers +using.linkage +using.overview +usrlit.suffix +util.dynamic.safety +util.smartptr +util.smartptr.atomic +util.smartptr.atomic.shared +util.smartptr.atomic.weak +util.smartptr.enab +util.smartptr.getdeleter +util.smartptr.hash +util.smartptr.ownerless +util.smartptr.shared +util.smartptr.shared.assign +util.smartptr.shared.atomic +util.smartptr.shared.cast +util.smartptr.shared.cmp +util.smartptr.shared.const +util.smartptr.shared.create +util.smartptr.shared.dest +util.smartptr.shared.io +util.smartptr.shared.mod +util.smartptr.shared.obs +util.smartptr.shared.spec +util.smartptr.weak +util.smartptr.weak.assign +util.smartptr.weak.bad +util.smartptr.weak.const +util.smartptr.weak.dest +util.smartptr.weak.mod +util.smartptr.weak.obs +util.smartptr.weak.spec +utilities +utilities.general +utility +utility.arg.requirements +utility.as.const +utility.as_const +utility.exchange +utility.from.chars +utility.intcmp +utility.requirements +utility.swap +utility.syn +utility.to.chars +utility.unreachable +valarray.access +valarray.assign +valarray.binary +valarray.cassign +valarray.comparison +valarray.cons +valarray.members +valarray.nonmembers +valarray.range +valarray.special +valarray.sub +valarray.syn +valarray.transcend +valarray.unary +value.error.codes +variant +variant.assign +variant.bad.access +variant.ctor +variant.dtor +variant.general +variant.get +variant.hash +variant.helper +variant.mod +variant.monostate +variant.monostate.relops +variant.relops +variant.specalg +variant.status +variant.swap +variant.syn +variant.traits +variant.variant +variant.visit +vector +vector.bool +vector.capacity +vector.cons +vector.data +vector.erasure +vector.modifiers +vector.overview +vector.special +vector.syn +version.syn +view.interface +view.interface.members +views +views.general +views.span +wide.stream.objects +zombie.names diff --git a/tools/check-output.sh b/tools/check-output.sh index 867e38e661..ccae6b348b 100755 --- a/tools/check-output.sh +++ b/tools/check-output.sh @@ -36,7 +36,7 @@ rm -f tmp.txt # Find bad labels grep newlabel `ls *.aux | grep -v std.aux` | awk -F '{' '{ print $2 }' | - sed 's/}//g' | sed 's/^tab://;s/fig://;s/idx.*\..//' | + sed 's/}//g' | sed 's/^tab://;s/fig://;s/eq://;s/idx.*\..//' | grep -v '^[a-z.0-9]*$' | sed 's/^\(.*\)$/bad label \1/' | fail || failed=1 @@ -48,6 +48,12 @@ cat std-grammarindex.ind | sed 's/^\(.*\)$/grammar non-terminal \1 has no definition/' | fail || failed=1 +# Find header index entries missing a definition +cat std-headerindex.ind | + awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } i=NF; while (i > 0 && $i !~ "<[a-z_.]*>") { --i; } item=$i; def=0; next } /hyperindexformat/ { def=1 }' | + sed 's/^\(.*\)$/header \1 has no definition/' | + fail || failed=1 + # Find concept index entries missing a definition cat std-conceptindex.ind | sed 's/.hyperindexformat/\nhyperindexformat/;s/.hyperpage/hyperpage/' | @@ -58,13 +64,21 @@ cat std-conceptindex.ind | # Find undecorated concept names in code blocks patt="`cat std-conceptindex.ind | sed 's/.hyperindexformat/\nhyperindexformat/;s/.hyperpage/\nhyperpage/' | - sed -n 's/^ .item.*{\([-a-z_]*\)}.*$/\1/p'`" + sed -n 's/^ .item.*{\([-a-z_]*\)}.*$/\1/p;s/^ .item.*frenchspacing \([a-z_]*\)}.*$/\1/p'`" patt="`echo $patt | sed 's/ /\\\\|/g'`" # $patt contains all concept names, separated by \| to use as a sed regex for f in *.tex; do - sed -n 's,//.*$,,;s/%.*$//;s/"[^"]*"/""/;/begin{codeblock\(tu\)\?}/,/end{codeblock\(tu\)\?}/{/[^-_{a-z\]\('"$patt"'\)[^-_}a-z();]/{=;p;};}' $f | + # handle codeblock + sed -n 's,//.*$,,;s/%.*$//;s/"[^"]*"/""/;/begin{codeblock\(tu\)\?}/,/end{codeblock\(tu\)\?}/{/[^-_a-z\]\('"$patt"'\)[^-_}a-z0-9();,]/{=;p;};}' $f | + # prefix output with filename and line + sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | + grep -v "@.seebelow" | + sed "s/\$/ -- concept name without markup/" | + fail || failed=1 + # handle itemdecl + sed -n 's,//.*$,,;s/%.*$//;s/"[^"]*"/""/;/begin{itemdecl}/,/end{itemdecl}/{/[^-_a-z]\('"$patt"'\)[^-_a-z();,]/{/concept{[a-z_-]*}/d;=;p;};}' $f | # prefix output with filename and line sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | grep -v "@.seebelow" | @@ -72,12 +86,12 @@ for f in *.tex; do fail || failed=1 done -# Cross references since the previous standard. -# Note: xrefprev should be a copy of the previous standard's xrefindex.glo. +# Cross references since C++17. +# Note: xrefprev should contain a sorted list of C++17 labels. function indexentries() { sed 's,\\glossaryentry{\(.*\)@.*,\1,' "$1" | LANG=C sort; } function removals() { diff -u "$1" "$2" | grep '^-' | grep -v '^---' | sed 's/^-//'; } function difference() { diff -u "$1" "$2" | grep '^[-+]' | grep -v '^\(---\|+++\)'; } -XREFDELTA="$(difference <(indexentries xrefdelta.glo) <(removals <(indexentries xrefprev) <(indexentries xrefindex.glo)))" +XREFDELTA="$(difference <(indexentries xrefdelta.glo) <(removals <(cat xrefprev) <(indexentries xrefindex.glo)))" if [ -n "$XREFDELTA" ]; then echo "incorrect entries in xrefdelta.tex:" >&2 echo "$XREFDELTA" | sed 's,^-,spurious ,; s,^+,missing ,;' >&2 diff --git a/tools/check-source.sh b/tools/check-source.sh index 5ddbdf9dfc..42596cfbb4 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 containers.tex iterators.tex ranges.tex algorithms.tex strings.tex text.tex numerics.tex time.tex iostreams.tex threads.tex exec.tex" texlib="lib-intro.tex $texlibdesc" # Filter that reformats the error message as a "workflow command", @@ -22,6 +22,9 @@ function fail() { } +# We require GNU tools. +sed --version | grep -Fqe "GNU sed" || { echo "sed is not GNU sed"; exit 1; } + # Find non-ASCII (Unicode) characters in the source LC_ALL=C grep -ne '[^ -~ ]' *.tex | fail 'non-ASCII character' || failed=1 @@ -170,7 +173,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 | diff --git a/tools/sections.cpp b/tools/sections.cpp index 0c658ea2da..b18d9a24e5 100644 --- a/tools/sections.cpp +++ b/tools/sections.cpp @@ -132,7 +132,7 @@ int main(int argc, char** argv) try { process(argv[1]); - } catch (std::exception e) { + } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 1; }